var gifsicle = (function () {
    let wasmUrl = "gifsicle.wasm";
    let FS_BAK = null;
    var gifsicle_c = (function () {
        var _scriptDir =
            typeof document !== "undefined" && document.currentScript
                ? document.currentScript.src
                : undefined;
        if (typeof __filename !== "undefined")
            _scriptDir = _scriptDir || __filename;
        return function (gifsicle) {
            gifsicle = gifsicle || {};

            var Module = typeof gifsicle !== "undefined" ? gifsicle : {};
            var readyPromiseResolve;
            Module["ready"] = new Promise(function (resolve, reject) {
                readyPromiseResolve = resolve;
            });
            Module.preRun = Module.preRun || [];
            Module.preRun.push(function writeInputFile() {
                if (Module.folder && Module.folder.length) {
                    for (let index = 0; index < Module.folder.length; index++) {
                        const element = Module.folder[index];
                        FS.mkdir(element);
                    }
                }

                FS.mkdir("/tem");
                FS.mkdir("/out");
                const data = Module.input;
                for (let index = 0; index < data.length; index++) {
                    const element = data[index];
                    FS.writeFile("/" + element.name, new Uint8Array(element.file));
                }
            });
            Module.postRun = Module.postRun || [];
            Module.postRun.push(function getOutputFile() {
                let outArr = [];
                let dir = FS.readdir("/out");
                // console.log(dir);
                dir.splice(0, 2);
                for (let index = 0; index < dir.length; index++) {
                    let path = dir[index];
                    let data = FS.readFile("/out/" + path);
                    outArr.push({
                        file: data,
                        name: path,
                    });
                }
                Module.output(outArr);
            });
            var moduleOverrides = {};
            var key;
            for (key in Module) {
                if (Module.hasOwnProperty(key)) {
                    moduleOverrides[key] = Module[key];
                }
            }
            var arguments_ = [];
            var thisProgram = "./this.program";
            var quit_ = function (status, toThrow) {
                throw toThrow;
            };
            var ENVIRONMENT_IS_WEB = false;
            var ENVIRONMENT_IS_WORKER = false;
            var ENVIRONMENT_IS_NODE = false;
            var ENVIRONMENT_IS_SHELL = false;
            ENVIRONMENT_IS_WEB = typeof window === "object";
            ENVIRONMENT_IS_WORKER = typeof importScripts === "function";
            ENVIRONMENT_IS_NODE =
                typeof process === "object" &&
                typeof process.versions === "object" &&
                typeof process.versions.node === "string";
            ENVIRONMENT_IS_SHELL =
                !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
            var scriptDirectory = "";

            function locateFile(path) {
                if (Module["locateFile"]) {
                    return Module["locateFile"](path, scriptDirectory);
                }
                return scriptDirectory + path;
            }
            var read_, readBinary;
            var nodeFS;
            var nodePath;
            if (ENVIRONMENT_IS_NODE) {
                if (ENVIRONMENT_IS_WORKER) {
                    scriptDirectory = require("path").dirname(scriptDirectory) + "/";
                } else {
                    scriptDirectory = __dirname + "/";
                }
                read_ = function shell_read(filename, binary) {
                    if (!nodeFS) nodeFS = require("fs");
                    if (!nodePath) nodePath = require("path");
                    filename = nodePath["normalize"](filename);
                    return nodeFS["readFileSync"](filename, binary ? null : "utf8");
                };
                readBinary = function readBinary(filename) {
                    var ret = read_(filename, true);
                    if (!ret.buffer) {
                        ret = new Uint8Array(ret);
                    }
                    assert(ret.buffer);
                    return ret;
                };
                if (process["argv"].length > 1) {
                    thisProgram = process["argv"][1].replace(/\\/g, "/");
                }
                arguments_ = process["argv"].slice(2);
                process["on"]("uncaughtException", function (ex) {
                    if (!(ex instanceof ExitStatus)) {
                        throw ex;
                    }
                });
                process["on"]("unhandledRejection", abort);
                quit_ = function (status) {
                    process["exit"](status);
                };
                Module["inspect"] = function () {
                    return "[Emscripten Module object]";
                };
            } else if (ENVIRONMENT_IS_SHELL) {
                if (typeof read != "undefined") {
                    read_ = function shell_read(f) {
                        return read(f);
                    };
                }
                readBinary = function readBinary(f) {
                    var data;
                    if (typeof readbuffer === "function") {
                        return new Uint8Array(readbuffer(f));
                    }
                    data = read(f, "binary");
                    assert(typeof data === "object");
                    return data;
                };
                if (typeof scriptArgs != "undefined") {
                    arguments_ = scriptArgs;
                } else if (typeof arguments != "undefined") {
                    arguments_ = arguments;
                }
                if (typeof quit === "function") {
                    quit_ = function (status) {
                        quit(status);
                    };
                }
                if (typeof print !== "undefined") {
                    if (typeof console === "undefined") console = {};
                    console.log = print;
                    console.warn = console.error =
                        typeof printErr !== "undefined" ? printErr : print;
                }
            } else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
                if (ENVIRONMENT_IS_WORKER) {
                    scriptDirectory = self.location.href;
                } else if (document.currentScript) {
                    scriptDirectory = document.currentScript.src;
                }
                if (_scriptDir) {
                    scriptDirectory = _scriptDir;
                }
                if (scriptDirectory.indexOf("blob:") !== 0) {
                    scriptDirectory = scriptDirectory.substr(
                        0,
                        scriptDirectory.lastIndexOf("/") + 1
                    );
                } else {
                    scriptDirectory = "";
                }
                {
                    read_ = function shell_read(url) {
                        var xhr = new XMLHttpRequest();
                        xhr.open("GET", url, false);
                        xhr.send(null);
                        return xhr.responseText;
                    };
                    if (ENVIRONMENT_IS_WORKER) {
                        readBinary = function readBinary(url) {
                            var xhr = new XMLHttpRequest();
                            xhr.open("GET", url, false);
                            xhr.responseType = "arraybuffer";
                            xhr.send(null);
                            return new Uint8Array(xhr.response);
                        };
                    }
                }
            } else;
            var out = Module["print"] || console.log.bind(console);
            var err = Module["printErr"] || console.warn.bind(console);
            for (key in moduleOverrides) {
                if (moduleOverrides.hasOwnProperty(key)) {
                    Module[key] = moduleOverrides[key];
                }
            }
            moduleOverrides = null;
            if (Module["arguments"]) arguments_ = Module["arguments"];
            if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
            if (Module["quit"]) quit_ = Module["quit"];
            var wasmBinary;
            if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"];
            var noExitRuntime;
            if (Module["noExitRuntime"]) noExitRuntime = Module["noExitRuntime"];
            if (typeof WebAssembly !== "object") {
                err("no native wasm support detected");
            }
            var wasmMemory;
            var wasmTable = new WebAssembly.Table({
                initial: 64,
                maximum: 64 + 0,
                element: "anyfunc",
            });
            var ABORT = false;

            function assert(condition, text) {
                if (!condition) {
                    abort("Assertion failed: " + text);
                }
            }
            var UTF8Decoder =
                typeof TextDecoder !== "undefined"
                    ? new TextDecoder("utf8")
                    : undefined;

            function UTF8ArrayToString(heap, idx, maxBytesToRead) {
                var endIdx = idx + maxBytesToRead;
                var endPtr = idx;
                while (heap[endPtr] && !(endPtr >= endIdx)) ++endPtr;
                if (endPtr - idx > 16 && heap.subarray && UTF8Decoder) {
                    return UTF8Decoder.decode(heap.subarray(idx, endPtr));
                } else {
                    var str = "";
                    while (idx < endPtr) {
                        var u0 = heap[idx++];
                        if (!(u0 & 128)) {
                            str += String.fromCharCode(u0);
                            continue;
                        }
                        var u1 = heap[idx++] & 63;
                        if ((u0 & 224) == 192) {
                            str += String.fromCharCode(((u0 & 31) << 6) | u1);
                            continue;
                        }
                        var u2 = heap[idx++] & 63;
                        if ((u0 & 240) == 224) {
                            u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
                        } else {
                            u0 =
                                ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | (heap[idx++] & 63);
                        }
                        if (u0 < 65536) {
                            str += String.fromCharCode(u0);
                        } else {
                            var ch = u0 - 65536;
                            str += String.fromCharCode(
                                55296 | (ch >> 10),
                                56320 | (ch & 1023)
                            );
                        }
                    }
                }
                return str;
            }

            function UTF8ToString(ptr, maxBytesToRead) {
                return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : "";
            }

            function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
                if (!(maxBytesToWrite > 0)) return 0;
                var startIdx = outIdx;
                var endIdx = outIdx + maxBytesToWrite - 1;
                for (var i = 0; i < str.length; ++i) {
                    var u = str.charCodeAt(i);
                    if (u >= 55296 && u <= 57343) {
                        var u1 = str.charCodeAt(++i);
                        u = (65536 + ((u & 1023) << 10)) | (u1 & 1023);
                    }
                    if (u <= 127) {
                        if (outIdx >= endIdx) break;
                        heap[outIdx++] = u;
                    } else if (u <= 2047) {
                        if (outIdx + 1 >= endIdx) break;
                        heap[outIdx++] = 192 | (u >> 6);
                        heap[outIdx++] = 128 | (u & 63);
                    } else if (u <= 65535) {
                        if (outIdx + 2 >= endIdx) break;
                        heap[outIdx++] = 224 | (u >> 12);
                        heap[outIdx++] = 128 | ((u >> 6) & 63);
                        heap[outIdx++] = 128 | (u & 63);
                    } else {
                        if (outIdx + 3 >= endIdx) break;
                        heap[outIdx++] = 240 | (u >> 18);
                        heap[outIdx++] = 128 | ((u >> 12) & 63);
                        heap[outIdx++] = 128 | ((u >> 6) & 63);
                        heap[outIdx++] = 128 | (u & 63);
                    }
                }
                heap[outIdx] = 0;
                return outIdx - startIdx;
            }

            function stringToUTF8(str, outPtr, maxBytesToWrite) {
                return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
            }

            function lengthBytesUTF8(str) {
                var len = 0;
                for (var i = 0; i < str.length; ++i) {
                    var u = str.charCodeAt(i);
                    if (u >= 55296 && u <= 57343)
                        u = (65536 + ((u & 1023) << 10)) | (str.charCodeAt(++i) & 1023);
                    if (u <= 127) ++len;
                    else if (u <= 2047) len += 2;
                    else if (u <= 65535) len += 3;
                    else len += 4;
                }
                return len;
            }

            function allocateUTF8OnStack(str) {
                var size = lengthBytesUTF8(str) + 1;
                var ret = stackAlloc(size);
                stringToUTF8Array(str, HEAP8, ret, size);
                return ret;
            }

            function writeAsciiToMemory(str, buffer, dontAddNull) {
                for (var i = 0; i < str.length; ++i) {
                    HEAP8[buffer++ >> 0] = str.charCodeAt(i);
                }
                if (!dontAddNull) HEAP8[buffer >> 0] = 0;
            }
            var WASM_PAGE_SIZE = 65536;

            function alignUp(x, multiple) {
                if (x % multiple > 0) {
                    x += multiple - (x % multiple);
                }
                return x;
            }
            var buffer, HEAP8, HEAPU8, HEAP16, HEAP32;

            function updateGlobalBufferAndViews(buf) {
                buffer = buf;
                Module["HEAP8"] = HEAP8 = new Int8Array(buf);
                Module["HEAP16"] = HEAP16 = new Int16Array(buf);
                Module["HEAP32"] = HEAP32 = new Int32Array(buf);
                Module["HEAPU8"] = HEAPU8 = new Uint8Array(buf);
                Module["HEAPU16"] = new Uint16Array(buf);
                Module["HEAPU32"] = new Uint32Array(buf);
                Module["HEAPF32"] = new Float32Array(buf);
                Module["HEAPF64"] = new Float64Array(buf);
            }
            var DYNAMIC_BASE = 5282144,
                DYNAMICTOP_PTR = 39104;
            var INITIAL_INITIAL_MEMORY = Module["INITIAL_MEMORY"] || 16777216;
            if (Module["wasmMemory"]) {
                wasmMemory = Module["wasmMemory"];
            } else {
                wasmMemory = new WebAssembly.Memory({
                    initial: INITIAL_INITIAL_MEMORY / WASM_PAGE_SIZE,
                    maximum: 2147483648 / WASM_PAGE_SIZE,
                });
            }
            if (wasmMemory) {
                buffer = wasmMemory.buffer;
            }
            INITIAL_INITIAL_MEMORY = buffer.byteLength;
            updateGlobalBufferAndViews(buffer);
            HEAP32[DYNAMICTOP_PTR >> 2] = DYNAMIC_BASE;

            function callRuntimeCallbacks(callbacks) {
                while (callbacks.length > 0) {
                    var callback = callbacks.shift();
                    if (typeof callback == "function") {
                        callback(Module);
                        continue;
                    }
                    var func = callback.func;
                    if (typeof func === "number") {
                        if (callback.arg === undefined) {
                            Module["dynCall_v"](func);
                        } else {
                            Module["dynCall_vi"](func, callback.arg);
                        }
                    } else {
                        func(callback.arg === undefined ? null : callback.arg);
                    }
                }
            }
            var __ATPRERUN__ = [];
            var __ATINIT__ = [];
            var __ATMAIN__ = [];
            var __ATPOSTRUN__ = [];

            function preRun() {
                if (Module["preRun"]) {
                    if (typeof Module["preRun"] == "function")
                        Module["preRun"] = [Module["preRun"]];
                    while (Module["preRun"].length) {
                        addOnPreRun(Module["preRun"].shift());
                    }
                }
                callRuntimeCallbacks(__ATPRERUN__);
            }

            function initRuntime() {
                if (!Module["noFSInit"] && !FS.init.initialized) FS.init();
                callRuntimeCallbacks(__ATINIT__);
            }

            function preMain() {
                FS.ignorePermissions = false;
                callRuntimeCallbacks(__ATMAIN__);
            }

            function postRun() {
                if (Module["postRun"]) {
                    if (typeof Module["postRun"] == "function")
                        Module["postRun"] = [Module["postRun"]];
                    while (Module["postRun"].length) {
                        addOnPostRun(Module["postRun"].shift());
                    }
                }
                callRuntimeCallbacks(__ATPOSTRUN__);
            }

            function addOnPreRun(cb) {
                __ATPRERUN__.unshift(cb);
            }

            function addOnPostRun(cb) {
                __ATPOSTRUN__.unshift(cb);
            }
            var Math_abs = Math.abs;
            var Math_ceil = Math.ceil;
            var Math_floor = Math.floor;
            var Math_min = Math.min;
            var runDependencies = 0;
            var dependenciesFulfilled = null;

            function addRunDependency(id) {
                runDependencies++;
                if (Module["monitorRunDependencies"]) {
                    Module["monitorRunDependencies"](runDependencies);
                }
            }

            function removeRunDependency(id) {
                runDependencies--;
                if (Module["monitorRunDependencies"]) {
                    Module["monitorRunDependencies"](runDependencies);
                }
                if (runDependencies == 0) {
                    if (dependenciesFulfilled) {
                        var callback = dependenciesFulfilled;
                        dependenciesFulfilled = null;
                        callback();
                    }
                }
            }
            Module["preloadedImages"] = {};
            Module["preloadedAudios"] = {};

            function abort(what) {
                if (Module["onAbort"]) {
                    Module["onAbort"](what);
                }
                what += "";
                out(what);
                err(what);
                ABORT = true;
                what = "abort(" + what + "). Build with -s ASSERTIONS=1 for more info.";
                throw new WebAssembly.RuntimeError(what);
            }

            function hasPrefix(str, prefix) {
                return String.prototype.startsWith
                    ? str.startsWith(prefix)
                    : str.indexOf(prefix) === 0;
            }
            var dataURIPrefix = "data:application/octet-stream;base64,";

            function isDataURI(filename) {
                return hasPrefix(filename, dataURIPrefix);
            }
            var fileURIPrefix = "file://";

            function isFileURI(filename) {
                return hasPrefix(filename, fileURIPrefix);
            }
            var wasmBinaryFile = wasmUrl;
            // if (!isDataURI(wasmBinaryFile)) {
            //     wasmBinaryFile = locateFile(wasmBinaryFile);
            // }

            function getBinary() {
                try {
                    if (wasmBinary) {
                        return new Uint8Array(wasmBinary);
                    }
                    if (readBinary) {
                        return readBinary(wasmBinaryFile);
                    } else {
                        throw "both async and sync fetching of the wasm failed";
                    }
                } catch (err) {
                    abort(err);
                }
            }

            function getBinaryPromise() {
                if (
                    !wasmBinary &&
                    (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) &&
                    typeof fetch === "function" &&
                    !isFileURI(wasmBinaryFile)
                ) {
                    return fetch(wasmBinaryFile, {
                        credentials: "same-origin",
                    })
                        .then(function (response) {
                            if (!response["ok"]) {
                                throw (
                                    "failed to load wasm binary file at '" + wasmBinaryFile + "'"
                                );
                            }
                            return response["arrayBuffer"]();
                        })
                        .catch(function () {
                            return getBinary();
                        });
                }
                return new Promise(function (resolve, reject) {
                    resolve(getBinary());
                });
            }

            function createWasm() {
                var info = {
                    a: asmLibraryArg,
                };

                function receiveInstance(instance, module) {
                    var exports = instance.exports;
                    Module["asm"] = exports;
                    removeRunDependency();
                }
                addRunDependency();

                function receiveInstantiatedSource(output) {
                    receiveInstance(output["instance"]);
                }

                function instantiateArrayBuffer(receiver) {
                    return getBinaryPromise()
                        .then(function (binary) {
                            return WebAssembly.instantiate(binary, info);
                        })
                        .then(receiver, function (reason) {
                            err("failed to asynchronously prepare wasm: " + reason);
                            abort(reason);
                        });
                }

                function instantiateAsync() {
                    if (
                        !wasmBinary &&
                        typeof WebAssembly.instantiateStreaming === "function" &&
                        !isDataURI(wasmBinaryFile) &&
                        !isFileURI(wasmBinaryFile) &&
                        typeof fetch === "function"
                    ) {
                        fetch(wasmBinaryFile, {
                            credentials: "same-origin",
                        }).then(function (response) {
                            var result = WebAssembly.instantiateStreaming(response, info);
                            return result.then(receiveInstantiatedSource, function (reason) {
                                err("wasm streaming compile failed: " + reason);
                                err("falling back to ArrayBuffer instantiation");
                                return instantiateArrayBuffer(receiveInstantiatedSource);
                            });
                        });
                    } else {
                        return instantiateArrayBuffer(receiveInstantiatedSource);
                    }
                }
                if (Module["instantiateWasm"]) {
                    try {
                        var exports = Module["instantiateWasm"](info, receiveInstance);
                        return exports;
                    } catch (e) {
                        err("Module.instantiateWasm callback failed with error: " + e);
                        return false;
                    }
                }
                instantiateAsync();
                return {};
            }
            var tempDouble;
            var tempI64;
            __ATINIT__.push({
                func: function () {
                    ___wasm_call_ctors();
                },
            });

            function demangle(func) {
                return func;
            }

            function demangleAll(text) {
                var regex = /\b_Z[\w\d_]+/g;
                return text.replace(regex, function (x) {
                    var y = demangle(x);
                    return x === y ? x : y + " [" + x + "]";
                });
            }

            function jsStackTrace() {
                var err = new Error();
                if (!err.stack) {
                    try {
                        throw new Error();
                    } catch (e) {
                        err = e;
                    }
                    if (!err.stack) {
                        return "(no stack trace available)";
                    }
                }
                return err.stack.toString();
            }

            function stackTrace() {
                var js = jsStackTrace();
                if (Module["extraStackTrace"]) js += "\n" + Module["extraStackTrace"]();
                return demangleAll(js);
            }

            function ___assert_fail(condition, filename, line, func) {
                abort(
                    "Assertion failed: " +
                    UTF8ToString(condition) +
                    ", at: " +
                    [
                        filename ? UTF8ToString(filename) : "unknown filename",
                        line,
                        func ? UTF8ToString(func) : "unknown function",
                    ]
                );
            }
            var _emscripten_get_now;
            if (ENVIRONMENT_IS_NODE) {
                _emscripten_get_now = function () {
                    var t = process["hrtime"]();
                    return t[0] * 1e3 + t[1] / 1e6;
                };
            } else if (typeof dateNow !== "undefined") {
                _emscripten_get_now = dateNow;
            } else
                _emscripten_get_now = function () {
                    return performance.now();
                };
            var _emscripten_get_now_is_monotonic = true;

            function setErrNo(value) {
                HEAP32[___errno_location() >> 2] = value;
                return value;
            }

            function _clock_gettime(clk_id, tp) {
                var now;
                if (clk_id === 0) {
                    now = Date.now();
                } else if (
                    (clk_id === 1 || clk_id === 4) &&
                    _emscripten_get_now_is_monotonic
                ) {
                    now = _emscripten_get_now();
                } else {
                    setErrNo(28);
                    return -1;
                }
                HEAP32[tp >> 2] = (now / 1e3) | 0;
                HEAP32[(tp + 4) >> 2] = ((now % 1e3) * 1e3 * 1e3) | 0;
                return 0;
            }

            function ___clock_gettime(a0, a1) {
                return _clock_gettime(a0, a1);
            }
            var PATH = {
                splitPath: function (filename) {
                    var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
                    return splitPathRe.exec(filename).slice(1);
                },
                normalizeArray: function (parts, allowAboveRoot) {
                    var up = 0;
                    for (var i = parts.length - 1; i >= 0; i--) {
                        var last = parts[i];
                        if (last === ".") {
                            parts.splice(i, 1);
                        } else if (last === "..") {
                            parts.splice(i, 1);
                            up++;
                        } else if (up) {
                            parts.splice(i, 1);
                            up--;
                        }
                    }
                    if (allowAboveRoot) {
                        for (; up; up--) {
                            parts.unshift("..");
                        }
                    }
                    return parts;
                },
                normalize: function (path) {
                    var isAbsolute = path.charAt(0) === "/",
                        trailingSlash = path.substr(-1) === "/";
                    path = PATH.normalizeArray(
                        path.split("/").filter(function (p) {
                            return !!p;
                        }),
                        !isAbsolute
                    ).join("/");
                    if (!path && !isAbsolute) {
                        path = ".";
                    }
                    if (path && trailingSlash) {
                        path += "/";
                    }
                    return (isAbsolute ? "/" : "") + path;
                },
                dirname: function (path) {
                    var result = PATH.splitPath(path),
                        root = result[0],
                        dir = result[1];
                    if (!root && !dir) {
                        return ".";
                    }
                    if (dir) {
                        dir = dir.substr(0, dir.length - 1);
                    }
                    return root + dir;
                },
                basename: function (path) {
                    if (path === "/") return "/";
                    var lastSlash = path.lastIndexOf("/");
                    if (lastSlash === -1) return path;
                    return path.substr(lastSlash + 1);
                },
                extname: function (path) {
                    return PATH.splitPath(path)[3];
                },
                join: function () {
                    var paths = Array.prototype.slice.call(arguments, 0);
                    return PATH.normalize(paths.join("/"));
                },
                join2: function (l, r) {
                    return PATH.normalize(l + "/" + r);
                },
            };
            var PATH_FS = {
                resolve: function () {
                    var resolvedPath = "",
                        resolvedAbsolute = false;
                    for (
                        var i = arguments.length - 1;
                        i >= -1 && !resolvedAbsolute;
                        i--
                    ) {
                        var path = i >= 0 ? arguments[i] : FS.cwd();
                        if (typeof path !== "string") {
                            throw new TypeError("Arguments to path.resolve must be strings");
                        } else if (!path) {
                            return "";
                        }
                        resolvedPath = path + "/" + resolvedPath;
                        resolvedAbsolute = path.charAt(0) === "/";
                    }
                    resolvedPath = PATH.normalizeArray(
                        resolvedPath.split("/").filter(function (p) {
                            return !!p;
                        }),
                        !resolvedAbsolute
                    ).join("/");
                    return (resolvedAbsolute ? "/" : "") + resolvedPath || ".";
                },
                relative: function (from, to) {
                    from = PATH_FS.resolve(from).substr(1);
                    to = PATH_FS.resolve(to).substr(1);

                    function trim(arr) {
                        var start = 0;
                        for (; start < arr.length; start++) {
                            if (arr[start] !== "") break;
                        }
                        var end = arr.length - 1;
                        for (; end >= 0; end--) {
                            if (arr[end] !== "") break;
                        }
                        if (start > end) return [];
                        return arr.slice(start, end - start + 1);
                    }
                    var fromParts = trim(from.split("/"));
                    var toParts = trim(to.split("/"));
                    var length = Math.min(fromParts.length, toParts.length);
                    var samePartsLength = length;
                    for (var i = 0; i < length; i++) {
                        if (fromParts[i] !== toParts[i]) {
                            samePartsLength = i;
                            break;
                        }
                    }
                    var outputParts = [];
                    for (var i = samePartsLength; i < fromParts.length; i++) {
                        outputParts.push("..");
                    }
                    outputParts = outputParts.concat(toParts.slice(samePartsLength));
                    return outputParts.join("/");
                },
            };
            var TTY = {
                ttys: [],
                init: function () { },
                shutdown: function () { },
                register: function (dev, ops) {
                    TTY.ttys[dev] = {
                        input: [],
                        output: [],
                        ops: ops,
                    };
                    FS.registerDevice(dev, TTY.stream_ops);
                },
                stream_ops: {
                    open: function (stream) {
                        var tty = TTY.ttys[stream.node.rdev];
                        if (!tty) {
                            throw new FS.ErrnoError(43);
                        }
                        stream.tty = tty;
                        stream.seekable = false;
                    },
                    close: function (stream) {
                        stream.tty.ops.flush(stream.tty);
                    },
                    flush: function (stream) {
                        stream.tty.ops.flush(stream.tty);
                    },
                    read: function (stream, buffer, offset, length, pos) {
                        if (!stream.tty || !stream.tty.ops.get_char) {
                            throw new FS.ErrnoError(60);
                        }
                        var bytesRead = 0;
                        for (var i = 0; i < length; i++) {
                            var result;
                            try {
                                result = stream.tty.ops.get_char(stream.tty);
                            } catch (e) {
                                throw new FS.ErrnoError(29);
                            }
                            if (result === undefined && bytesRead === 0) {
                                throw new FS.ErrnoError(6);
                            }
                            if (result === null || result === undefined) break;
                            bytesRead++;
                            buffer[offset + i] = result;
                        }
                        if (bytesRead) {
                            stream.node.timestamp = Date.now();
                        }
                        return bytesRead;
                    },
                    write: function (stream, buffer, offset, length, pos) {
                        if (!stream.tty || !stream.tty.ops.put_char) {
                            throw new FS.ErrnoError(60);
                        }
                        try {
                            for (var i = 0; i < length; i++) {
                                stream.tty.ops.put_char(stream.tty, buffer[offset + i]);
                            }
                        } catch (e) {
                            throw new FS.ErrnoError(29);
                        }
                        if (length) {
                            stream.node.timestamp = Date.now();
                        }
                        return i;
                    },
                },
                default_tty_ops: {
                    get_char: function (tty) {
                        if (!tty.input.length) {
                            var result = null;
                            if (ENVIRONMENT_IS_NODE) {
                                var BUFSIZE = 256;
                                var buf = Buffer.alloc
                                    ? Buffer.alloc(BUFSIZE)
                                    : new Buffer(BUFSIZE);
                                var bytesRead = 0;
                                try {
                                    bytesRead = nodeFS.readSync(
                                        process.stdin.fd,
                                        buf,
                                        0,
                                        BUFSIZE,
                                        null
                                    );
                                } catch (e) {
                                    if (e.toString().indexOf("EOF") != -1) bytesRead = 0;
                                    else throw e;
                                }
                                if (bytesRead > 0) {
                                    result = buf.slice(0, bytesRead).toString("utf-8");
                                } else {
                                    result = null;
                                }
                            } else if (
                                typeof window != "undefined" &&
                                typeof window.prompt == "function"
                            ) {
                                result = window.prompt("Input: ");
                                if (result !== null) {
                                    result += "\n";
                                }
                            } else if (typeof readline == "function") {
                                result = readline();
                                if (result !== null) {
                                    result += "\n";
                                }
                            }
                            if (!result) {
                                return null;
                            }
                            tty.input = intArrayFromString(result, true);
                        }
                        return tty.input.shift();
                    },
                    put_char: function (tty, val) {
                        if (val === null || val === 10) {
                            out(UTF8ArrayToString(tty.output, 0));
                            tty.output = [];
                        } else {
                            if (val != 0) tty.output.push(val);
                        }
                    },
                    flush: function (tty) {
                        if (tty.output && tty.output.length > 0) {
                            out(UTF8ArrayToString(tty.output, 0));
                            tty.output = [];
                        }
                    },
                },
                default_tty1_ops: {
                    put_char: function (tty, val) {
                        if (val === null || val === 10) {
                            err(UTF8ArrayToString(tty.output, 0));
                            tty.output = [];
                        } else {
                            if (val != 0) tty.output.push(val);
                        }
                    },
                    flush: function (tty) {
                        if (tty.output && tty.output.length > 0) {
                            err(UTF8ArrayToString(tty.output, 0));
                            tty.output = [];
                        }
                    },
                },
            };
            var MEMFS = {
                ops_table: null,
                mount: function (mount) {
                    return MEMFS.createNode(null, "/", 16384 | 511, 0);
                },
                createNode: function (parent, name, mode, dev) {
                    if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
                        throw new FS.ErrnoError(63);
                    }
                    if (!MEMFS.ops_table) {
                        MEMFS.ops_table = {
                            dir: {
                                node: {
                                    getattr: MEMFS.node_ops.getattr,
                                    setattr: MEMFS.node_ops.setattr,
                                    lookup: MEMFS.node_ops.lookup,
                                    mknod: MEMFS.node_ops.mknod,
                                    rename: MEMFS.node_ops.rename,
                                    unlink: MEMFS.node_ops.unlink,
                                    rmdir: MEMFS.node_ops.rmdir,
                                    readdir: MEMFS.node_ops.readdir,
                                    symlink: MEMFS.node_ops.symlink,
                                },
                                stream: {
                                    llseek: MEMFS.stream_ops.llseek,
                                },
                            },
                            file: {
                                node: {
                                    getattr: MEMFS.node_ops.getattr,
                                    setattr: MEMFS.node_ops.setattr,
                                },
                                stream: {
                                    llseek: MEMFS.stream_ops.llseek,
                                    read: MEMFS.stream_ops.read,
                                    write: MEMFS.stream_ops.write,
                                    allocate: MEMFS.stream_ops.allocate,
                                    mmap: MEMFS.stream_ops.mmap,
                                    msync: MEMFS.stream_ops.msync,
                                },
                            },
                            link: {
                                node: {
                                    getattr: MEMFS.node_ops.getattr,
                                    setattr: MEMFS.node_ops.setattr,
                                    readlink: MEMFS.node_ops.readlink,
                                },
                                stream: {},
                            },
                            chrdev: {
                                node: {
                                    getattr: MEMFS.node_ops.getattr,
                                    setattr: MEMFS.node_ops.setattr,
                                },
                                stream: FS.chrdev_stream_ops,
                            },
                        };
                    }
                    var node = FS.createNode(parent, name, mode, dev);
                    if (FS.isDir(node.mode)) {
                        node.node_ops = MEMFS.ops_table.dir.node;
                        node.stream_ops = MEMFS.ops_table.dir.stream;
                        node.contents = {};
                    } else if (FS.isFile(node.mode)) {
                        node.node_ops = MEMFS.ops_table.file.node;
                        node.stream_ops = MEMFS.ops_table.file.stream;
                        node.usedBytes = 0;
                        node.contents = null;
                    } else if (FS.isLink(node.mode)) {
                        node.node_ops = MEMFS.ops_table.link.node;
                        node.stream_ops = MEMFS.ops_table.link.stream;
                    } else if (FS.isChrdev(node.mode)) {
                        node.node_ops = MEMFS.ops_table.chrdev.node;
                        node.stream_ops = MEMFS.ops_table.chrdev.stream;
                    }
                    node.timestamp = Date.now();
                    if (parent) {
                        parent.contents[name] = node;
                    }
                    return node;
                },
                getFileDataAsRegularArray: function (node) {
                    if (node.contents && node.contents.subarray) {
                        var arr = [];
                        for (var i = 0; i < node.usedBytes; ++i) arr.push(node.contents[i]);
                        return arr;
                    }
                    return node.contents;
                },
                getFileDataAsTypedArray: function (node) {
                    if (!node.contents) return new Uint8Array(0);
                    if (node.contents.subarray)
                        return node.contents.subarray(0, node.usedBytes);
                    return new Uint8Array(node.contents);
                },
                expandFileStorage: function (node, newCapacity) {
                    var prevCapacity = node.contents ? node.contents.length : 0;
                    if (prevCapacity >= newCapacity) return;
                    var CAPACITY_DOUBLING_MAX = 1024 * 1024;
                    newCapacity = Math.max(
                        newCapacity,
                        (prevCapacity *
                            (prevCapacity < CAPACITY_DOUBLING_MAX ? 2 : 1.125)) >>>
                        0
                    );
                    if (prevCapacity != 0) newCapacity = Math.max(newCapacity, 256);
                    var oldContents = node.contents;
                    node.contents = new Uint8Array(newCapacity);
                    if (node.usedBytes > 0)
                        node.contents.set(oldContents.subarray(0, node.usedBytes), 0);
                    return;
                },
                resizeFileStorage: function (node, newSize) {
                    if (node.usedBytes == newSize) return;
                    if (newSize == 0) {
                        node.contents = null;
                        node.usedBytes = 0;
                        return;
                    }
                    if (!node.contents || node.contents.subarray) {
                        var oldContents = node.contents;
                        node.contents = new Uint8Array(newSize);
                        if (oldContents) {
                            node.contents.set(
                                oldContents.subarray(0, Math.min(newSize, node.usedBytes))
                            );
                        }
                        node.usedBytes = newSize;
                        return;
                    }
                    if (!node.contents) node.contents = [];
                    if (node.contents.length > newSize) node.contents.length = newSize;
                    else while (node.contents.length < newSize) node.contents.push(0);
                    node.usedBytes = newSize;
                },
                node_ops: {
                    getattr: function (node) {
                        var attr = {};
                        attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
                        attr.ino = node.id;
                        attr.mode = node.mode;
                        attr.nlink = 1;
                        attr.uid = 0;
                        attr.gid = 0;
                        attr.rdev = node.rdev;
                        if (FS.isDir(node.mode)) {
                            attr.size = 4096;
                        } else if (FS.isFile(node.mode)) {
                            attr.size = node.usedBytes;
                        } else if (FS.isLink(node.mode)) {
                            attr.size = node.link.length;
                        } else {
                            attr.size = 0;
                        }
                        attr.atime = new Date(node.timestamp);
                        attr.mtime = new Date(node.timestamp);
                        attr.ctime = new Date(node.timestamp);
                        attr.blksize = 4096;
                        attr.blocks = Math.ceil(attr.size / attr.blksize);
                        return attr;
                    },
                    setattr: function (node, attr) {
                        if (attr.mode !== undefined) {
                            node.mode = attr.mode;
                        }
                        if (attr.timestamp !== undefined) {
                            node.timestamp = attr.timestamp;
                        }
                        if (attr.size !== undefined) {
                            MEMFS.resizeFileStorage(node, attr.size);
                        }
                    },
                    lookup: function (parent, name) {
                        throw FS.genericErrors[44];
                    },
                    mknod: function (parent, name, mode, dev) {
                        return MEMFS.createNode(parent, name, mode, dev);
                    },
                    rename: function (old_node, new_dir, new_name) {
                        if (FS.isDir(old_node.mode)) {
                            var new_node;
                            try {
                                new_node = FS.lookupNode(new_dir, new_name);
                            } catch (e) { }
                            if (new_node) {
                                for (var i in new_node.contents) {
                                    throw new FS.ErrnoError(55);
                                }
                            }
                        }
                        delete old_node.parent.contents[old_node.name];
                        old_node.name = new_name;
                        new_dir.contents[new_name] = old_node;
                        old_node.parent = new_dir;
                    },
                    unlink: function (parent, name) {
                        delete parent.contents[name];
                    },
                    rmdir: function (parent, name) {
                        var node = FS.lookupNode(parent, name);
                        for (var i in node.contents) {
                            throw new FS.ErrnoError(55);
                        }
                        delete parent.contents[name];
                    },
                    readdir: function (node) {
                        var entries = [".", ".."];
                        for (var key in node.contents) {
                            if (!node.contents.hasOwnProperty(key)) {
                                continue;
                            }
                            entries.push(key);
                        }
                        return entries;
                    },
                    symlink: function (parent, newname, oldpath) {
                        var node = MEMFS.createNode(parent, newname, 511 | 40960, 0);
                        node.link = oldpath;
                        return node;
                    },
                    readlink: function (node) {
                        if (!FS.isLink(node.mode)) {
                            throw new FS.ErrnoError(28);
                        }
                        return node.link;
                    },
                },
                stream_ops: {
                    read: function (stream, buffer, offset, length, position) {
                        var contents = stream.node.contents;
                        if (position >= stream.node.usedBytes) return 0;
                        var size = Math.min(stream.node.usedBytes - position, length);
                        if (size > 8 && contents.subarray) {
                            buffer.set(contents.subarray(position, position + size), offset);
                        } else {
                            for (var i = 0; i < size; i++)
                                buffer[offset + i] = contents[position + i];
                        }
                        return size;
                    },
                    write: function (stream, buffer, offset, length, position, canOwn) {
                        if (buffer.buffer === HEAP8.buffer) {
                            canOwn = false;
                        }
                        if (!length) return 0;
                        var node = stream.node;
                        node.timestamp = Date.now();
                        if (buffer.subarray && (!node.contents || node.contents.subarray)) {
                            if (canOwn) {
                                node.contents = buffer.subarray(offset, offset + length);
                                node.usedBytes = length;
                                return length;
                            } else if (node.usedBytes === 0 && position === 0) {
                                node.contents = buffer.slice(offset, offset + length);
                                node.usedBytes = length;
                                return length;
                            } else if (position + length <= node.usedBytes) {
                                node.contents.set(
                                    buffer.subarray(offset, offset + length),
                                    position
                                );
                                return length;
                            }
                        }
                        MEMFS.expandFileStorage(node, position + length);
                        if (node.contents.subarray && buffer.subarray)
                            node.contents.set(
                                buffer.subarray(offset, offset + length),
                                position
                            );
                        else {
                            for (var i = 0; i < length; i++) {
                                node.contents[position + i] = buffer[offset + i];
                            }
                        }
                        node.usedBytes = Math.max(node.usedBytes, position + length);
                        return length;
                    },
                    llseek: function (stream, offset, whence) {
                        var position = offset;
                        if (whence === 1) {
                            position += stream.position;
                        } else if (whence === 2) {
                            if (FS.isFile(stream.node.mode)) {
                                position += stream.node.usedBytes;
                            }
                        }
                        if (position < 0) {
                            throw new FS.ErrnoError(28);
                        }
                        return position;
                    },
                    allocate: function (stream, offset, length) {
                        MEMFS.expandFileStorage(stream.node, offset + length);
                        stream.node.usedBytes = Math.max(
                            stream.node.usedBytes,
                            offset + length
                        );
                    },
                    mmap: function (stream, address, length, position, prot, flags) {
                        assert(address === 0);
                        if (!FS.isFile(stream.node.mode)) {
                            throw new FS.ErrnoError(43);
                        }
                        var ptr;
                        var allocated;
                        var contents = stream.node.contents;
                        if (!(flags & 2) && contents.buffer === buffer) {
                            allocated = false;
                            ptr = contents.byteOffset;
                        } else {
                            if (position > 0 || position + length < contents.length) {
                                if (contents.subarray) {
                                    contents = contents.subarray(position, position + length);
                                } else {
                                    contents = Array.prototype.slice.call(
                                        contents,
                                        position,
                                        position + length
                                    );
                                }
                            }
                            allocated = true;
                            ptr = _malloc(length);
                            if (!ptr) {
                                throw new FS.ErrnoError(48);
                            }
                            HEAP8.set(contents, ptr);
                        }
                        return {
                            ptr: ptr,
                            allocated: allocated,
                        };
                    },
                    msync: function (stream, buffer, offset, length, mmapFlags) {
                        if (!FS.isFile(stream.node.mode)) {
                            throw new FS.ErrnoError(43);
                        }
                        if (mmapFlags & 2) {
                            return 0;
                        }
                        MEMFS.stream_ops.write(stream, buffer, 0, length, offset, false);
                        return 0;
                    },
                },
            };
            var FS = FS_BAK || {
                root: null,
                mounts: [],
                devices: {},
                streams: [],
                nextInode: 1,
                nameTable: null,
                currentPath: "/",
                initialized: false,
                ignorePermissions: true,
                trackingDelegate: {},
                tracking: {
                    openFlags: {
                        READ: 1,
                        WRITE: 2,
                    },
                },
                ErrnoError: null,
                genericErrors: {},
                filesystems: null,
                syncFSRequests: 0,
                handleFSError: function (e) {
                    if (!(e instanceof FS.ErrnoError)) throw e + " : " + stackTrace();
                    return setErrNo(e.errno);
                },
                lookupPath: function (path, opts) {
                    path = PATH_FS.resolve(FS.cwd(), path);
                    opts = opts || {};
                    if (!path)
                        return {
                            path: "",
                            node: null,
                        };
                    var defaults = {
                        follow_mount: true,
                        recurse_count: 0,
                    };
                    for (var key in defaults) {
                        if (opts[key] === undefined) {
                            opts[key] = defaults[key];
                        }
                    }
                    if (opts.recurse_count > 8) {
                        throw new FS.ErrnoError(32);
                    }
                    var parts = PATH.normalizeArray(
                        path.split("/").filter(function (p) {
                            return !!p;
                        }),
                        false
                    );
                    var current = FS.root;
                    var current_path = "/";
                    for (var i = 0; i < parts.length; i++) {
                        var islast = i === parts.length - 1;
                        if (islast && opts.parent) {
                            break;
                        }
                        current = FS.lookupNode(current, parts[i]);
                        current_path = PATH.join2(current_path, parts[i]);
                        if (FS.isMountpoint(current)) {
                            if (!islast || (islast && opts.follow_mount)) {
                                current = current.mounted.root;
                            }
                        }
                        if (!islast || opts.follow) {
                            var count = 0;
                            while (FS.isLink(current.mode)) {
                                var link = FS.readlink(current_path);
                                current_path = PATH_FS.resolve(
                                    PATH.dirname(current_path),
                                    link
                                );
                                var lookup = FS.lookupPath(current_path, {
                                    recurse_count: opts.recurse_count,
                                });
                                current = lookup.node;
                                if (count++ > 40) {
                                    throw new FS.ErrnoError(32);
                                }
                            }
                        }
                    }
                    return {
                        path: current_path,
                        node: current,
                    };
                },
                getPath: function (node) {
                    var path;
                    while (true) {
                        if (FS.isRoot(node)) {
                            var mount = node.mount.mountpoint;
                            if (!path) return mount;
                            return mount[mount.length - 1] !== "/"
                                ? mount + "/" + path
                                : mount + path;
                        }
                        path = path ? node.name + "/" + path : node.name;
                        node = node.parent;
                    }
                },
                hashName: function (parentid, name) {
                    var hash = 0;
                    for (var i = 0; i < name.length; i++) {
                        hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
                    }
                    return ((parentid + hash) >>> 0) % FS.nameTable.length;
                },
                hashAddNode: function (node) {
                    var hash = FS.hashName(node.parent.id, node.name);
                    node.name_next = FS.nameTable[hash];
                    FS.nameTable[hash] = node;
                },
                hashRemoveNode: function (node) {
                    var hash = FS.hashName(node.parent.id, node.name);
                    if (FS.nameTable[hash] === node) {
                        FS.nameTable[hash] = node.name_next;
                    } else {
                        var current = FS.nameTable[hash];
                        while (current) {
                            if (current.name_next === node) {
                                current.name_next = node.name_next;
                                break;
                            }
                            current = current.name_next;
                        }
                    }
                },
                lookupNode: function (parent, name) {
                    var errCode = FS.mayLookup(parent);
                    if (errCode) {
                        throw new FS.ErrnoError(errCode, parent);
                    }
                    var hash = FS.hashName(parent.id, name);
                    for (var node = FS.nameTable[hash]; node; node = node.name_next) {
                        var nodeName = node.name;
                        if (node.parent.id === parent.id && nodeName === name) {
                            return node;
                        }
                    }
                    return FS.lookup(parent, name);
                },
                createNode: function (parent, name, mode, rdev) {
                    var node = new FS.FSNode(parent, name, mode, rdev);
                    FS.hashAddNode(node);
                    return node;
                },
                destroyNode: function (node) {
                    FS.hashRemoveNode(node);
                },
                isRoot: function (node) {
                    return node === node.parent;
                },
                isMountpoint: function (node) {
                    return !!node.mounted;
                },
                isFile: function (mode) {
                    return (mode & 61440) === 32768;
                },
                isDir: function (mode) {
                    return (mode & 61440) === 16384;
                },
                isLink: function (mode) {
                    return (mode & 61440) === 40960;
                },
                isChrdev: function (mode) {
                    return (mode & 61440) === 8192;
                },
                isBlkdev: function (mode) {
                    return (mode & 61440) === 24576;
                },
                isFIFO: function (mode) {
                    return (mode & 61440) === 4096;
                },
                isSocket: function (mode) {
                    return (mode & 49152) === 49152;
                },
                flagModes: {
                    r: 0,
                    rs: 1052672,
                    "r+": 2,
                    w: 577,
                    wx: 705,
                    xw: 705,
                    "w+": 578,
                    "wx+": 706,
                    "xw+": 706,
                    a: 1089,
                    ax: 1217,
                    xa: 1217,
                    "a+": 1090,
                    "ax+": 1218,
                    "xa+": 1218,
                },
                modeStringToFlags: function (str) {
                    var flags = FS.flagModes[str];
                    if (typeof flags === "undefined") {
                        throw new Error("Unknown file open mode: " + str);
                    }
                    return flags;
                },
                flagsToPermissionString: function (flag) {
                    var perms = ["r", "w", "rw"][flag & 3];
                    if (flag & 512) {
                        perms += "w";
                    }
                    return perms;
                },
                nodePermissions: function (node, perms) {
                    if (FS.ignorePermissions) {
                        return 0;
                    }
                    if (perms.indexOf("r") !== -1 && !(node.mode & 292)) {
                        return 2;
                    } else if (perms.indexOf("w") !== -1 && !(node.mode & 146)) {
                        return 2;
                    } else if (perms.indexOf("x") !== -1 && !(node.mode & 73)) {
                        return 2;
                    }
                    return 0;
                },
                mayLookup: function (dir) {
                    var errCode = FS.nodePermissions(dir, "x");
                    if (errCode) return errCode;
                    if (!dir.node_ops.lookup) return 2;
                    return 0;
                },
                mayCreate: function (dir, name) {
                    try {
                        var node = FS.lookupNode(dir, name);
                        return 20;
                    } catch (e) { }
                    return FS.nodePermissions(dir, "wx");
                },
                mayDelete: function (dir, name, isdir) {
                    var node;
                    try {
                        node = FS.lookupNode(dir, name);
                    } catch (e) {
                        return e.errno;
                    }
                    var errCode = FS.nodePermissions(dir, "wx");
                    if (errCode) {
                        return errCode;
                    }
                    if (isdir) {
                        if (!FS.isDir(node.mode)) {
                            return 54;
                        }
                        if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
                            return 10;
                        }
                    } else {
                        if (FS.isDir(node.mode)) {
                            return 31;
                        }
                    }
                    return 0;
                },
                mayOpen: function (node, flags) {
                    if (!node) {
                        return 44;
                    }
                    if (FS.isLink(node.mode)) {
                        return 32;
                    } else if (FS.isDir(node.mode)) {
                        if (FS.flagsToPermissionString(flags) !== "r" || flags & 512) {
                            return 31;
                        }
                    }
                    return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
                },
                MAX_OPEN_FDS: 4096,
                nextfd: function (fd_start, fd_end) {
                    fd_start = fd_start || 0;
                    fd_end = fd_end || FS.MAX_OPEN_FDS;
                    for (var fd = fd_start; fd <= fd_end; fd++) {
                        if (!FS.streams[fd]) {
                            return fd;
                        }
                    }
                    throw new FS.ErrnoError(33);
                },
                getStream: function (fd) {
                    return FS.streams[fd];
                },
                createStream: function (stream, fd_start, fd_end) {
                    if (!FS.FSStream) {
                        FS.FSStream = function () { };
                        FS.FSStream.prototype = {
                            object: {
                                get: function () {
                                    return this.node;
                                },
                                set: function (val) {
                                    this.node = val;
                                },
                            },
                            isRead: {
                                get: function () {
                                    return (this.flags & 2097155) !== 1;
                                },
                            },
                            isWrite: {
                                get: function () {
                                    return (this.flags & 2097155) !== 0;
                                },
                            },
                            isAppend: {
                                get: function () {
                                    return this.flags & 1024;
                                },
                            },
                        };
                    }
                    var newStream = new FS.FSStream();
                    for (var p in stream) {
                        newStream[p] = stream[p];
                    }
                    stream = newStream;
                    var fd = FS.nextfd(fd_start, fd_end);
                    stream.fd = fd;
                    FS.streams[fd] = stream;
                    return stream;
                },
                closeStream: function (fd) {
                    FS.streams[fd] = null;
                },
                chrdev_stream_ops: {
                    open: function (stream) {
                        var device = FS.getDevice(stream.node.rdev);
                        stream.stream_ops = device.stream_ops;
                        if (stream.stream_ops.open) {
                            stream.stream_ops.open(stream);
                        }
                    },
                    llseek: function () {
                        throw new FS.ErrnoError(70);
                    },
                },
                major: function (dev) {
                    return dev >> 8;
                },
                minor: function (dev) {
                    return dev & 255;
                },
                makedev: function (ma, mi) {
                    return (ma << 8) | mi;
                },
                registerDevice: function (dev, ops) {
                    FS.devices[dev] = {
                        stream_ops: ops,
                    };
                },
                getDevice: function (dev) {
                    return FS.devices[dev];
                },
                getMounts: function (mount) {
                    var mounts = [];
                    var check = [mount];
                    while (check.length) {
                        var m = check.pop();
                        mounts.push(m);
                        check.push.apply(check, m.mounts);
                    }
                    return mounts;
                },
                syncfs: function (populate, callback) {
                    if (typeof populate === "function") {
                        callback = populate;
                        populate = false;
                    }
                    FS.syncFSRequests++;
                    if (FS.syncFSRequests > 1) {
                        err(
                            "warning: " +
                            FS.syncFSRequests +
                            " FS.syncfs operations in flight at once, probably just doing extra work"
                        );
                    }
                    var mounts = FS.getMounts(FS.root.mount);
                    var completed = 0;

                    function doCallback(errCode) {
                        FS.syncFSRequests--;
                        return callback(errCode);
                    }

                    function done(errCode) {
                        if (errCode) {
                            if (!done.errored) {
                                done.errored = true;
                                return doCallback(errCode);
                            }
                            return;
                        }
                        if (++completed >= mounts.length) {
                            doCallback(null);
                        }
                    }
                    mounts.forEach(function (mount) {
                        if (!mount.type.syncfs) {
                            return done(null);
                        }
                        mount.type.syncfs(mount, populate, done);
                    });
                },
                mount: function (type, opts, mountpoint) {
                    var root = mountpoint === "/";
                    var pseudo = !mountpoint;
                    var node;
                    if (root && FS.root) {
                        throw new FS.ErrnoError(10);
                    } else if (!root && !pseudo) {
                        var lookup = FS.lookupPath(mountpoint, {
                            follow_mount: false,
                        });
                        mountpoint = lookup.path;
                        node = lookup.node;
                        if (FS.isMountpoint(node)) {
                            throw new FS.ErrnoError(10);
                        }
                        if (!FS.isDir(node.mode)) {
                            throw new FS.ErrnoError(54);
                        }
                    }
                    var mount = {
                        type: type,
                        opts: opts,
                        mountpoint: mountpoint,
                        mounts: [],
                    };
                    var mountRoot = type.mount(mount);
                    mountRoot.mount = mount;
                    mount.root = mountRoot;
                    if (root) {
                        FS.root = mountRoot;
                    } else if (node) {
                        node.mounted = mount;
                        if (node.mount) {
                            node.mount.mounts.push(mount);
                        }
                    }
                    return mountRoot;
                },
                unmount: function (mountpoint) {
                    var lookup = FS.lookupPath(mountpoint, {
                        follow_mount: false,
                    });
                    if (!FS.isMountpoint(lookup.node)) {
                        throw new FS.ErrnoError(28);
                    }
                    var node = lookup.node;
                    var mount = node.mounted;
                    var mounts = FS.getMounts(mount);
                    Object.keys(FS.nameTable).forEach(function (hash) {
                        var current = FS.nameTable[hash];
                        while (current) {
                            var next = current.name_next;
                            if (mounts.indexOf(current.mount) !== -1) {
                                FS.destroyNode(current);
                            }
                            current = next;
                        }
                    });
                    node.mounted = null;
                    var idx = node.mount.mounts.indexOf(mount);
                    node.mount.mounts.splice(idx, 1);
                },
                lookup: function (parent, name) {
                    return parent.node_ops.lookup(parent, name);
                },
                mknod: function (path, mode, dev) {
                    var lookup = FS.lookupPath(path, {
                        parent: true,
                    });
                    var parent = lookup.node;
                    var name = PATH.basename(path);
                    if (!name || name === "." || name === "..") {
                        throw new FS.ErrnoError(28);
                    }
                    var errCode = FS.mayCreate(parent, name);
                    if (errCode) {
                        throw new FS.ErrnoError(errCode);
                    }
                    if (!parent.node_ops.mknod) {
                        throw new FS.ErrnoError(63);
                    }
                    return parent.node_ops.mknod(parent, name, mode, dev);
                },
                create: function (path, mode) {
                    mode = mode !== undefined ? mode : 438;
                    mode &= 4095;
                    mode |= 32768;
                    return FS.mknod(path, mode, 0);
                },
                mkdir: function (path, mode) {
                    mode = mode !== undefined ? mode : 511;
                    mode &= 511 | 512;
                    mode |= 16384;
                    return FS.mknod(path, mode, 0);
                },
                mkdirTree: function (path, mode) {
                    var dirs = path.split("/");
                    var d = "";
                    for (var i = 0; i < dirs.length; ++i) {
                        if (!dirs[i]) continue;
                        d += "/" + dirs[i];
                        try {
                            FS.mkdir(d, mode);
                        } catch (e) {
                            if (e.errno != 20) throw e;
                        }
                    }
                },
                mkdev: function (path, mode, dev) {
                    if (typeof dev === "undefined") {
                        dev = mode;
                        mode = 438;
                    }
                    mode |= 8192;
                    return FS.mknod(path, mode, dev);
                },
                symlink: function (oldpath, newpath) {
                    if (!PATH_FS.resolve(oldpath)) {
                        throw new FS.ErrnoError(44);
                    }
                    var lookup = FS.lookupPath(newpath, {
                        parent: true,
                    });
                    var parent = lookup.node;
                    if (!parent) {
                        throw new FS.ErrnoError(44);
                    }
                    var newname = PATH.basename(newpath);
                    var errCode = FS.mayCreate(parent, newname);
                    if (errCode) {
                        throw new FS.ErrnoError(errCode);
                    }
                    if (!parent.node_ops.symlink) {
                        throw new FS.ErrnoError(63);
                    }
                    return parent.node_ops.symlink(parent, newname, oldpath);
                },
                rename: function (old_path, new_path) {
                    var old_dirname = PATH.dirname(old_path);
                    var new_dirname = PATH.dirname(new_path);
                    var old_name = PATH.basename(old_path);
                    var new_name = PATH.basename(new_path);
                    var lookup, old_dir, new_dir;
                    try {
                        lookup = FS.lookupPath(old_path, {
                            parent: true,
                        });
                        old_dir = lookup.node;
                        lookup = FS.lookupPath(new_path, {
                            parent: true,
                        });
                        new_dir = lookup.node;
                    } catch (e) {
                        throw new FS.ErrnoError(10);
                    }
                    if (!old_dir || !new_dir) throw new FS.ErrnoError(44);
                    if (old_dir.mount !== new_dir.mount) {
                        throw new FS.ErrnoError(75);
                    }
                    var old_node = FS.lookupNode(old_dir, old_name);
                    var relative = PATH_FS.relative(old_path, new_dirname);
                    if (relative.charAt(0) !== ".") {
                        throw new FS.ErrnoError(28);
                    }
                    relative = PATH_FS.relative(new_path, old_dirname);
                    if (relative.charAt(0) !== ".") {
                        throw new FS.ErrnoError(55);
                    }
                    var new_node;
                    try {
                        new_node = FS.lookupNode(new_dir, new_name);
                    } catch (e) { }
                    if (old_node === new_node) {
                        return;
                    }
                    var isdir = FS.isDir(old_node.mode);
                    var errCode = FS.mayDelete(old_dir, old_name, isdir);
                    if (errCode) {
                        throw new FS.ErrnoError(errCode);
                    }
                    errCode = new_node
                        ? FS.mayDelete(new_dir, new_name, isdir)
                        : FS.mayCreate(new_dir, new_name);
                    if (errCode) {
                        throw new FS.ErrnoError(errCode);
                    }
                    if (!old_dir.node_ops.rename) {
                        throw new FS.ErrnoError(63);
                    }
                    if (
                        FS.isMountpoint(old_node) ||
                        (new_node && FS.isMountpoint(new_node))
                    ) {
                        throw new FS.ErrnoError(10);
                    }
                    if (new_dir !== old_dir) {
                        errCode = FS.nodePermissions(old_dir, "w");
                        if (errCode) {
                            throw new FS.ErrnoError(errCode);
                        }
                    }
                    try {
                        if (FS.trackingDelegate["willMovePath"]);
                    } catch (e) {
                        err(
                            "FS.trackingDelegate['willMovePath']('" +
                            old_path +
                            "', '" +
                            new_path +
                            "') threw an exception: " +
                            e.message
                        );
                    }
                    FS.hashRemoveNode(old_node);
                    try {
                        old_dir.node_ops.rename(old_node, new_dir, new_name);
                    } catch (e) {
                        throw e;
                    } finally {
                        FS.hashAddNode(old_node);
                    }
                    try {
                        if (FS.trackingDelegate["onMovePath"]);
                    } catch (e) {
                        err(
                            "FS.trackingDelegate['onMovePath']('" +
                            old_path +
                            "', '" +
                            new_path +
                            "') threw an exception: " +
                            e.message
                        );
                    }
                },
                rmdir: function (path) {
                    var lookup = FS.lookupPath(path, {
                        parent: true,
                    });
                    var parent = lookup.node;
                    var name = PATH.basename(path);
                    var node = FS.lookupNode(parent, name);
                    var errCode = FS.mayDelete(parent, name, true);
                    if (errCode) {
                        throw new FS.ErrnoError(errCode);
                    }
                    if (!parent.node_ops.rmdir) {
                        throw new FS.ErrnoError(63);
                    }
                    if (FS.isMountpoint(node)) {
                        throw new FS.ErrnoError(10);
                    }
                    try {
                        if (FS.trackingDelegate["willDeletePath"]);
                    } catch (e) {
                        err(
                            "FS.trackingDelegate['willDeletePath']('" +
                            path +
                            "') threw an exception: " +
                            e.message
                        );
                    }
                    parent.node_ops.rmdir(parent, name);
                    FS.destroyNode(node);
                    try {
                        if (FS.trackingDelegate["onDeletePath"]);
                    } catch (e) {
                        err(
                            "FS.trackingDelegate['onDeletePath']('" +
                            path +
                            "') threw an exception: " +
                            e.message
                        );
                    }
                },
                readdir: function (path) {
                    var lookup = FS.lookupPath(path, {
                        follow: true,
                    });
                    var node = lookup.node;
                    if (!node.node_ops.readdir) {
                        throw new FS.ErrnoError(54);
                    }
                    return node.node_ops.readdir(node);
                },
                unlink: function (path) {
                    var lookup = FS.lookupPath(path, {
                        parent: true,
                    });
                    var parent = lookup.node;
                    var name = PATH.basename(path);
                    var node = FS.lookupNode(parent, name);
                    var errCode = FS.mayDelete(parent, name, false);
                    if (errCode) {
                        throw new FS.ErrnoError(errCode);
                    }
                    if (!parent.node_ops.unlink) {
                        throw new FS.ErrnoError(63);
                    }
                    if (FS.isMountpoint(node)) {
                        throw new FS.ErrnoError(10);
                    }
                    try {
                        if (FS.trackingDelegate["willDeletePath"]);
                    } catch (e) {
                        err(
                            "FS.trackingDelegate['willDeletePath']('" +
                            path +
                            "') threw an exception: " +
                            e.message
                        );
                    }
                    parent.node_ops.unlink(parent, name);
                    FS.destroyNode(node);
                    try {
                        if (FS.trackingDelegate["onDeletePath"]);
                    } catch (e) {
                        err(
                            "FS.trackingDelegate['onDeletePath']('" +
                            path +
                            "') threw an exception: " +
                            e.message
                        );
                    }
                },
                readlink: function (path) {
                    var lookup = FS.lookupPath(path);
                    var link = lookup.node;
                    if (!link) {
                        throw new FS.ErrnoError(44);
                    }
                    if (!link.node_ops.readlink) {
                        throw new FS.ErrnoError(28);
                    }
                    return PATH_FS.resolve(
                        FS.getPath(link.parent),
                        link.node_ops.readlink(link)
                    );
                },
                stat: function (path, dontFollow) {
                    var lookup = FS.lookupPath(path, {
                        follow: !dontFollow,
                    });
                    var node = lookup.node;
                    if (!node) {
                        throw new FS.ErrnoError(44);
                    }
                    if (!node.node_ops.getattr) {
                        throw new FS.ErrnoError(63);
                    }
                    return node.node_ops.getattr(node);
                },
                lstat: function (path) {
                    return FS.stat(path, true);
                },
                chmod: function (path, mode, dontFollow) {
                    var node;
                    if (typeof path === "string") {
                        var lookup = FS.lookupPath(path, {
                            follow: !dontFollow,
                        });
                        node = lookup.node;
                    } else {
                        node = path;
                    }
                    if (!node.node_ops.setattr) {
                        throw new FS.ErrnoError(63);
                    }
                    node.node_ops.setattr(node, {
                        mode: (mode & 4095) | (node.mode & ~4095),
                        timestamp: Date.now(),
                    });
                },
                lchmod: function (path, mode) {
                    FS.chmod(path, mode, true);
                },
                fchmod: function (fd, mode) {
                    var stream = FS.getStream(fd);
                    if (!stream) {
                        throw new FS.ErrnoError(8);
                    }
                    FS.chmod(stream.node, mode);
                },
                chown: function (path, uid, gid, dontFollow) {
                    var node;
                    if (typeof path === "string") {
                        var lookup = FS.lookupPath(path, {
                            follow: !dontFollow,
                        });
                        node = lookup.node;
                    } else {
                        node = path;
                    }
                    if (!node.node_ops.setattr) {
                        throw new FS.ErrnoError(63);
                    }
                    node.node_ops.setattr(node, {
                        timestamp: Date.now(),
                    });
                },
                lchown: function (path, uid, gid) {
                    FS.chown(path, uid, gid, true);
                },
                fchown: function (fd, uid, gid) {
                    var stream = FS.getStream(fd);
                    if (!stream) {
                        throw new FS.ErrnoError(8);
                    }
                    FS.chown(stream.node, uid, gid);
                },
                truncate: function (path, len) {
                    if (len < 0) {
                        throw new FS.ErrnoError(28);
                    }
                    var node;
                    if (typeof path === "string") {
                        var lookup = FS.lookupPath(path, {
                            follow: true,
                        });
                        node = lookup.node;
                    } else {
                        node = path;
                    }
                    if (!node.node_ops.setattr) {
                        throw new FS.ErrnoError(63);
                    }
                    if (FS.isDir(node.mode)) {
                        throw new FS.ErrnoError(31);
                    }
                    if (!FS.isFile(node.mode)) {
                        throw new FS.ErrnoError(28);
                    }
                    var errCode = FS.nodePermissions(node, "w");
                    if (errCode) {
                        throw new FS.ErrnoError(errCode);
                    }
                    node.node_ops.setattr(node, {
                        size: len,
                        timestamp: Date.now(),
                    });
                },
                ftruncate: function (fd, len) {
                    var stream = FS.getStream(fd);
                    if (!stream) {
                        throw new FS.ErrnoError(8);
                    }
                    if ((stream.flags & 2097155) === 0) {
                        throw new FS.ErrnoError(28);
                    }
                    FS.truncate(stream.node, len);
                },
                utime: function (path, atime, mtime) {
                    var lookup = FS.lookupPath(path, {
                        follow: true,
                    });
                    var node = lookup.node;
                    node.node_ops.setattr(node, {
                        timestamp: Math.max(atime, mtime),
                    });
                },
                open: function (path, flags, mode, fd_start, fd_end) {
                    if (path === "") {
                        throw new FS.ErrnoError(44);
                    }
                    flags =
                        typeof flags === "string" ? FS.modeStringToFlags(flags) : flags;
                    mode = typeof mode === "undefined" ? 438 : mode;
                    if (flags & 64) {
                        mode = (mode & 4095) | 32768;
                    } else {
                        mode = 0;
                    }
                    var node;
                    if (typeof path === "object") {
                        node = path;
                    } else {
                        path = PATH.normalize(path);
                        try {
                            var lookup = FS.lookupPath(path, {
                                follow: !(flags & 131072),
                            });
                            node = lookup.node;
                        } catch (e) { }
                    }
                    var created = false;
                    if (flags & 64) {
                        if (node) {
                            if (flags & 128) {
                                throw new FS.ErrnoError(20);
                            }
                        } else {
                            node = FS.mknod(path, mode, 0);
                            created = true;
                        }
                    }
                    if (!node) {
                        throw new FS.ErrnoError(44);
                    }
                    if (FS.isChrdev(node.mode)) {
                        flags &= ~512;
                    }
                    if (flags & 65536 && !FS.isDir(node.mode)) {
                        throw new FS.ErrnoError(54);
                    }
                    if (!created) {
                        var errCode = FS.mayOpen(node, flags);
                        if (errCode) {
                            throw new FS.ErrnoError(errCode);
                        }
                    }
                    if (flags & 512) {
                        FS.truncate(node, 0);
                    }
                    flags &= ~(128 | 512 | 131072);
                    var stream = FS.createStream(
                        {
                            node: node,
                            path: FS.getPath(node),
                            flags: flags,
                            seekable: true,
                            position: 0,
                            stream_ops: node.stream_ops,
                            ungotten: [],
                            error: false,
                        },
                        fd_start,
                        fd_end
                    );
                    if (stream.stream_ops.open) {
                        stream.stream_ops.open(stream);
                    }
                    if (Module["logReadFiles"] && !(flags & 1)) {
                        if (!FS.readFiles) FS.readFiles = {};
                        if (!(path in FS.readFiles)) {
                            FS.readFiles[path] = 1;
                            err("FS.trackingDelegate error on read file: " + path);
                        }
                    }
                    try {
                        var trackingFlags;
                        if (FS.trackingDelegate["onOpenFile"]);
                    } catch (e) {
                        err(
                            "FS.trackingDelegate['onOpenFile']('" +
                            path +
                            "', flags) threw an exception: " +
                            e.message
                        );
                    }
                    return stream;
                },
                close: function (stream) {
                    if (FS.isClosed(stream)) {
                        throw new FS.ErrnoError(8);
                    }
                    if (stream.getdents) stream.getdents = null;
                    try {
                        if (stream.stream_ops.close) {
                            stream.stream_ops.close(stream);
                        }
                    } catch (e) {
                        throw e;
                    } finally {
                        FS.closeStream(stream.fd);
                    }
                    stream.fd = null;
                },
                isClosed: function (stream) {
                    return stream.fd === null;
                },
                llseek: function (stream, offset, whence) {
                    if (FS.isClosed(stream)) {
                        throw new FS.ErrnoError(8);
                    }
                    if (!stream.seekable || !stream.stream_ops.llseek) {
                        throw new FS.ErrnoError(70);
                    }
                    if (whence != 0 && whence != 1 && whence != 2) {
                        throw new FS.ErrnoError(28);
                    }
                    stream.position = stream.stream_ops.llseek(stream, offset, whence);
                    stream.ungotten = [];
                    return stream.position;
                },
                read: function (stream, buffer, offset, length, position) {
                    if (length < 0 || position < 0) {
                        throw new FS.ErrnoError(28);
                    }
                    if (FS.isClosed(stream)) {
                        throw new FS.ErrnoError(8);
                    }
                    if ((stream.flags & 2097155) === 1) {
                        throw new FS.ErrnoError(8);
                    }
                    if (FS.isDir(stream.node.mode)) {
                        throw new FS.ErrnoError(31);
                    }
                    if (!stream.stream_ops.read) {
                        throw new FS.ErrnoError(28);
                    }
                    var seeking = typeof position !== "undefined";
                    if (!seeking) {
                        position = stream.position;
                    } else if (!stream.seekable) {
                        throw new FS.ErrnoError(70);
                    }
                    var bytesRead = stream.stream_ops.read(
                        stream,
                        buffer,
                        offset,
                        length,
                        position
                    );
                    if (!seeking) stream.position += bytesRead;
                    return bytesRead;
                },
                write: function (stream, buffer, offset, length, position, canOwn) {
                    if (length < 0 || position < 0) {
                        throw new FS.ErrnoError(28);
                    }
                    if (FS.isClosed(stream)) {
                        throw new FS.ErrnoError(8);
                    }
                    if ((stream.flags & 2097155) === 0) {
                        throw new FS.ErrnoError(8);
                    }
                    if (FS.isDir(stream.node.mode)) {
                        throw new FS.ErrnoError(31);
                    }
                    if (!stream.stream_ops.write) {
                        throw new FS.ErrnoError(28);
                    }
                    if (stream.seekable && stream.flags & 1024) {
                        FS.llseek(stream, 0, 2);
                    }
                    var seeking = typeof position !== "undefined";
                    if (!seeking) {
                        position = stream.position;
                    } else if (!stream.seekable) {
                        throw new FS.ErrnoError(70);
                    }
                    var bytesWritten = stream.stream_ops.write(
                        stream,
                        buffer,
                        offset,
                        length,
                        position,
                        canOwn
                    );
                    if (!seeking) stream.position += bytesWritten;
                    try {
                        if (stream.path && FS.trackingDelegate["onWriteToFile"])
                            FS.trackingDelegate["onWriteToFile"](stream.path);
                    } catch (e) {
                        err(
                            "FS.trackingDelegate['onWriteToFile']('" +
                            stream.path +
                            "') threw an exception: " +
                            e.message
                        );
                    }
                    return bytesWritten;
                },
                allocate: function (stream, offset, length) {
                    if (FS.isClosed(stream)) {
                        throw new FS.ErrnoError(8);
                    }
                    if (offset < 0 || length <= 0) {
                        throw new FS.ErrnoError(28);
                    }
                    if ((stream.flags & 2097155) === 0) {
                        throw new FS.ErrnoError(8);
                    }
                    if (!FS.isFile(stream.node.mode) && !FS.isDir(stream.node.mode)) {
                        throw new FS.ErrnoError(43);
                    }
                    if (!stream.stream_ops.allocate) {
                        throw new FS.ErrnoError(138);
                    }
                    stream.stream_ops.allocate(stream, offset, length);
                },
                mmap: function (stream, address, length, position, prot, flags) {
                    if (
                        (prot & 2) !== 0 &&
                        (flags & 2) === 0 &&
                        (stream.flags & 2097155) !== 2
                    ) {
                        throw new FS.ErrnoError(2);
                    }
                    if ((stream.flags & 2097155) === 1) {
                        throw new FS.ErrnoError(2);
                    }
                    if (!stream.stream_ops.mmap) {
                        throw new FS.ErrnoError(43);
                    }
                    return stream.stream_ops.mmap(
                        stream,
                        address,
                        length,
                        position,
                        prot,
                        flags
                    );
                },
                msync: function (stream, buffer, offset, length, mmapFlags) {
                    if (!stream || !stream.stream_ops.msync) {
                        return 0;
                    }
                    return stream.stream_ops.msync(
                        stream,
                        buffer,
                        offset,
                        length,
                        mmapFlags
                    );
                },
                munmap: function (stream) {
                    return 0;
                },
                ioctl: function (stream, cmd, arg) {
                    if (!stream.stream_ops.ioctl) {
                        throw new FS.ErrnoError(59);
                    }
                    return stream.stream_ops.ioctl(stream, cmd, arg);
                },
                readFile: function (path, opts) {
                    opts = opts || {};
                    opts.flags = opts.flags || "r";
                    opts.encoding = opts.encoding || "binary";
                    if (opts.encoding !== "utf8" && opts.encoding !== "binary") {
                        throw new Error('Invalid encoding type "' + opts.encoding + '"');
                    }
                    var ret;
                    var stream = FS.open(path, opts.flags);
                    var stat = FS.stat(path);
                    var length = stat.size;
                    var buf = new Uint8Array(length);
                    FS.read(stream, buf, 0, length, 0);
                    if (opts.encoding === "utf8") {
                        ret = UTF8ArrayToString(buf, 0);
                    } else if (opts.encoding === "binary") {
                        ret = buf;
                    }
                    FS.close(stream);
                    return ret;
                },
                writeFile: function (path, data, opts) {
                    opts = opts || {};
                    opts.flags = opts.flags || "w";
                    var stream = FS.open(path, opts.flags, opts.mode);
                    if (typeof data === "string") {
                        var buf = new Uint8Array(lengthBytesUTF8(data) + 1);
                        var actualNumBytes = stringToUTF8Array(data, buf, 0, buf.length);
                        FS.write(stream, buf, 0, actualNumBytes, undefined, opts.canOwn);
                    } else if (ArrayBuffer.isView(data)) {
                        FS.write(stream, data, 0, data.byteLength, undefined, opts.canOwn);
                    } else {
                        throw new Error("Unsupported data type");
                    }
                    FS.close(stream);
                },
                cwd: function () {
                    return FS.currentPath;
                },
                chdir: function (path) {
                    var lookup = FS.lookupPath(path, {
                        follow: true,
                    });
                    if (lookup.node === null) {
                        throw new FS.ErrnoError(44);
                    }
                    if (!FS.isDir(lookup.node.mode)) {
                        throw new FS.ErrnoError(54);
                    }
                    var errCode = FS.nodePermissions(lookup.node, "x");
                    if (errCode) {
                        throw new FS.ErrnoError(errCode);
                    }
                    FS.currentPath = lookup.path;
                },
                createDefaultDirectories: function () {
                    FS.mkdir("/tmp");
                    FS.mkdir("/home");
                    FS.mkdir("/home/web_user");
                },
                createDefaultDevices: function () {
                    FS.mkdir("/dev");
                    FS.registerDevice(FS.makedev(1, 3), {
                        read: function () {
                            return 0;
                        },
                        write: function (stream, buffer, offset, length, pos) {
                            return length;
                        },
                    });
                    FS.mkdev("/dev/null", FS.makedev(1, 3));
                    TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
                    TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
                    FS.mkdev("/dev/tty", FS.makedev(5, 0));
                    FS.mkdev("/dev/tty1", FS.makedev(6, 0));
                    var random_device;
                    if (
                        typeof crypto === "object" &&
                        typeof crypto["getRandomValues"] === "function"
                    ) {
                        var randomBuffer = new Uint8Array(1);
                        random_device = function () {
                            crypto.getRandomValues(randomBuffer);
                            return randomBuffer[0];
                        };
                    } else if (ENVIRONMENT_IS_NODE) {
                        try {
                            var crypto_module = require("crypto");
                            random_device = function () {
                                return crypto_module["randomBytes"](1)[0];
                            };
                        } catch (e) { }
                    } else;
                    if (!random_device) {
                        random_device = function () {
                            abort("random_device");
                        };
                    }
                    FS.createDevice("/dev", "random", random_device);
                    FS.createDevice("/dev", "urandom", random_device);
                    FS.mkdir("/dev/shm");
                    FS.mkdir("/dev/shm/tmp");
                },
                createSpecialDirectories: function () {
                    FS.mkdir("/proc");
                    FS.mkdir("/proc/self");
                    FS.mkdir("/proc/self/fd");
                    FS.mount(
                        {
                            mount: function () {
                                var node = FS.createNode("/proc/self", "fd", 16384 | 511, 73);
                                node.node_ops = {
                                    lookup: function (parent, name) {
                                        var fd = +name;
                                        var stream = FS.getStream(fd);
                                        if (!stream) throw new FS.ErrnoError(8);
                                        var ret = {
                                            parent: null,
                                            mount: {
                                                mountpoint: "fake",
                                            },
                                            node_ops: {
                                                readlink: function () {
                                                    return stream.path;
                                                },
                                            },
                                        };
                                        ret.parent = ret;
                                        return ret;
                                    },
                                };
                                return node;
                            },
                        },
                        {},
                        "/proc/self/fd"
                    );
                },
                createStandardStreams: function () {
                    if (Module["stdin"]) {
                        FS.createDevice("/dev", "stdin", Module["stdin"]);
                    } else {
                        FS.symlink("/dev/tty", "/dev/stdin");
                    }
                    if (Module["stdout"]) {
                        FS.createDevice("/dev", "stdout", null, Module["stdout"]);
                    } else {
                        FS.symlink("/dev/tty", "/dev/stdout");
                    }
                    if (Module["stderr"]) {
                        FS.createDevice("/dev", "stderr", null, Module["stderr"]);
                    } else {
                        FS.symlink("/dev/tty1", "/dev/stderr");
                    }
                    FS.open("/dev/stdin", "r");
                    FS.open("/dev/stdout", "w");
                    FS.open("/dev/stderr", "w");
                },
                ensureErrnoError: function () {
                    if (FS.ErrnoError) return;
                    FS.ErrnoError = function ErrnoError(errno, node) {
                        this.node = node;
                        this.setErrno = function (errno) {
                            this.errno = errno;
                        };
                        this.setErrno(errno);
                        this.message = "FS error";
                    };
                    FS.ErrnoError.prototype = new Error();
                    FS.ErrnoError.prototype.constructor = FS.ErrnoError;
                    [44].forEach(function (code) {
                        FS.genericErrors[code] = new FS.ErrnoError(code);
                        FS.genericErrors[code].stack = "<generic error, no stack>";
                    });
                },
                staticInit: function () {
                    FS.ensureErrnoError();
                    FS.nameTable = new Array(4096);
                    FS.mount(MEMFS, {}, "/");
                    FS.createDefaultDirectories();
                    FS.createDefaultDevices();
                    FS.createSpecialDirectories();
                    FS.filesystems = {
                        MEMFS: MEMFS,
                    };
                },
                init: function (input, output, error) {
                    FS.init.initialized = true;
                    FS.ensureErrnoError();
                    Module["stdin"] = input || Module["stdin"];
                    Module["stdout"] = output || Module["stdout"];
                    Module["stderr"] = error || Module["stderr"];
                    FS.createStandardStreams();
                },
                quit: function () {
                    FS.init.initialized = false;
                    var fflush = Module["_fflush"];
                    if (fflush) fflush(0);
                    for (var i = 0; i < FS.streams.length; i++) {
                        var stream = FS.streams[i];
                        if (!stream) {
                            continue;
                        }
                        FS.close(stream);
                    }
                },
                getMode: function (canRead, canWrite) {
                    var mode = 0;
                    if (canRead) mode |= 292 | 73;
                    if (canWrite) mode |= 146;
                    return mode;
                },
                joinPath: function (parts, forceRelative) {
                    var path = PATH.join.apply(null, parts);
                    if (forceRelative && path[0] == "/") path = path.substr(1);
                    return path;
                },
                absolutePath: function (relative, base) {
                    return PATH_FS.resolve(base, relative);
                },
                standardizePath: function (path) {
                    return PATH.normalize(path);
                },
                findObject: function (path, dontResolveLastLink) {
                    var ret = FS.analyzePath(path, dontResolveLastLink);
                    if (ret.exists) {
                        return ret.object;
                    } else {
                        setErrNo(ret.error);
                        return null;
                    }
                },
                analyzePath: function (path, dontResolveLastLink) {
                    try {
                        var lookup = FS.lookupPath(path, {
                            follow: !dontResolveLastLink,
                        });
                        path = lookup.path;
                    } catch (e) { }
                    var ret = {
                        isRoot: false,
                        exists: false,
                        error: 0,
                        name: null,
                        path: null,
                        object: null,
                        parentExists: false,
                        parentPath: null,
                        parentObject: null,
                    };
                    try {
                        var lookup = FS.lookupPath(path, {
                            parent: true,
                        });
                        ret.parentExists = true;
                        ret.parentPath = lookup.path;
                        ret.parentObject = lookup.node;
                        ret.name = PATH.basename(path);
                        lookup = FS.lookupPath(path, {
                            follow: !dontResolveLastLink,
                        });
                        ret.exists = true;
                        ret.path = lookup.path;
                        ret.object = lookup.node;
                        ret.name = lookup.node.name;
                        ret.isRoot = lookup.path === "/";
                    } catch (e) {
                        ret.error = e.errno;
                    }
                    return ret;
                },
                createFolder: function (parent, name, canRead, canWrite) {
                    var path = PATH.join2(
                        typeof parent === "string" ? parent : FS.getPath(parent),
                        name
                    );
                    var mode = FS.getMode(canRead, canWrite);
                    return FS.mkdir(path, mode);
                },
                createPath: function (parent, path, canRead, canWrite) {
                    parent = typeof parent === "string" ? parent : FS.getPath(parent);
                    var parts = path.split("/").reverse();
                    while (parts.length) {
                        var part = parts.pop();
                        if (!part) continue;
                        var current = PATH.join2(parent, part);
                        try {
                            FS.mkdir(current);
                        } catch (e) { }
                        parent = current;
                    }
                    return current;
                },
                createFile: function (parent, name, properties, canRead, canWrite) {
                    var path = PATH.join2(
                        typeof parent === "string" ? parent : FS.getPath(parent),
                        name
                    );
                    var mode = FS.getMode(canRead, canWrite);
                    return FS.create(path, mode);
                },
                createDataFile: function (
                    parent,
                    name,
                    data,
                    canRead,
                    canWrite,
                    canOwn
                ) {
                    var path = name
                        ? PATH.join2(
                            typeof parent === "string" ? parent : FS.getPath(parent),
                            name
                        )
                        : parent;
                    var mode = FS.getMode(canRead, canWrite);
                    var node = FS.create(path, mode);
                    if (data) {
                        if (typeof data === "string") {
                            var arr = new Array(data.length);
                            for (var i = 0, len = data.length; i < len; ++i)
                                arr[i] = data.charCodeAt(i);
                            data = arr;
                        }
                        FS.chmod(node, mode | 146);
                        var stream = FS.open(node, "w");
                        FS.write(stream, data, 0, data.length, 0, canOwn);
                        FS.close(stream);
                        FS.chmod(node, mode);
                    }
                    return node;
                },
                createDevice: function (parent, name, input, output) {
                    var path = PATH.join2(
                        typeof parent === "string" ? parent : FS.getPath(parent),
                        name
                    );
                    var mode = FS.getMode(!!input, !!output);
                    if (!FS.createDevice.major) FS.createDevice.major = 64;
                    var dev = FS.makedev(FS.createDevice.major++, 0);
                    FS.registerDevice(dev, {
                        open: function (stream) {
                            stream.seekable = false;
                        },
                        close: function (stream) {
                            if (output && output.buffer && output.buffer.length) {
                                output(10);
                            }
                        },
                        read: function (stream, buffer, offset, length, pos) {
                            var bytesRead = 0;
                            for (var i = 0; i < length; i++) {
                                var result;
                                try {
                                    result = input();
                                } catch (e) {
                                    throw new FS.ErrnoError(29);
                                }
                                if (result === undefined && bytesRead === 0) {
                                    throw new FS.ErrnoError(6);
                                }
                                if (result === null || result === undefined) break;
                                bytesRead++;
                                buffer[offset + i] = result;
                            }
                            if (bytesRead) {
                                stream.node.timestamp = Date.now();
                            }
                            return bytesRead;
                        },
                        write: function (stream, buffer, offset, length, pos) {
                            for (var i = 0; i < length; i++) {
                                try {
                                    output(buffer[offset + i]);
                                } catch (e) {
                                    throw new FS.ErrnoError(29);
                                }
                            }
                            if (length) {
                                stream.node.timestamp = Date.now();
                            }
                            return i;
                        },
                    });
                    return FS.mkdev(path, mode, dev);
                },
                createLink: function (parent, name, target, canRead, canWrite) {
                    var path = PATH.join2(
                        typeof parent === "string" ? parent : FS.getPath(parent),
                        name
                    );
                    return FS.symlink(target, path);
                },
                forceLoadFile: function (obj) {
                    if (obj.isDevice || obj.isFolder || obj.link || obj.contents)
                        return true;
                    var success = true;
                    if (typeof XMLHttpRequest !== "undefined") {
                        throw new Error(
                            "Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread."
                        );
                    } else if (read_) {
                        try {
                            obj.contents = intArrayFromString(read_(obj.url), true);
                            obj.usedBytes = obj.contents.length;
                        } catch (e) {
                            success = false;
                        }
                    } else {
                        throw new Error("Cannot load without read() or XMLHttpRequest.");
                    }
                    if (!success) setErrNo(29);
                    return success;
                },
                createLazyFile: function (parent, name, url, canRead, canWrite) {
                    function LazyUint8Array() {
                        this.lengthKnown = false;
                        this.chunks = [];
                    }
                    LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
                        if (idx > this.length - 1 || idx < 0) {
                            return undefined;
                        }
                        var chunkOffset = idx % this.chunkSize;
                        var chunkNum = (idx / this.chunkSize) | 0;
                        return this.getter(chunkNum)[chunkOffset];
                    };
                    LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(
                        getter
                    ) {
                        this.getter = getter;
                    };
                    LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
                        var xhr = new XMLHttpRequest();
                        xhr.open("HEAD", url, false);
                        xhr.send(null);
                        if (
                            !((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304)
                        )
                            throw new Error(
                                "Couldn't load " + url + ". Status: " + xhr.status
                            );
                        var datalength = Number(xhr.getResponseHeader("Content-length"));
                        var header;
                        var hasByteServing =
                            (header = xhr.getResponseHeader("Accept-Ranges")) &&
                            header === "bytes";
                        var usesGzip =
                            (header = xhr.getResponseHeader("Content-Encoding")) &&
                            header === "gzip";
                        var chunkSize = 1024 * 1024;
                        if (!hasByteServing) chunkSize = datalength;
                        var doXHR = function (from, to) {
                            if (from > to)
                                throw new Error(
                                    "invalid range (" +
                                    from +
                                    ", " +
                                    to +
                                    ") or no bytes requested!"
                                );
                            if (to > datalength - 1)
                                throw new Error(
                                    "only " + datalength + " bytes available! programmer error!"
                                );
                            var xhr = new XMLHttpRequest();
                            xhr.open("GET", url, false);
                            if (datalength !== chunkSize)
                                xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
                            if (typeof Uint8Array != "undefined")
                                xhr.responseType = "arraybuffer";
                            if (xhr.overrideMimeType) {
                                xhr.overrideMimeType("text/plain; charset=x-user-defined");
                            }
                            xhr.send(null);
                            if (
                                !((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304)
                            )
                                throw new Error(
                                    "Couldn't load " + url + ". Status: " + xhr.status
                                );
                            if (xhr.response !== undefined) {
                                return new Uint8Array(xhr.response || []);
                            } else {
                                return intArrayFromString(xhr.responseText || "", true);
                            }
                        };
                        var lazyArray = this;
                        lazyArray.setDataGetter(function (chunkNum) {
                            var start = chunkNum * chunkSize;
                            var end = (chunkNum + 1) * chunkSize - 1;
                            end = Math.min(end, datalength - 1);
                            if (typeof lazyArray.chunks[chunkNum] === "undefined") {
                                lazyArray.chunks[chunkNum] = doXHR(start, end);
                            }
                            if (typeof lazyArray.chunks[chunkNum] === "undefined")
                                throw new Error("doXHR failed!");
                            return lazyArray.chunks[chunkNum];
                        });
                        if (usesGzip || !datalength) {
                            chunkSize = datalength = 1;
                            datalength = this.getter(0).length;
                            chunkSize = datalength;
                            out(
                                "LazyFiles on gzip forces download of the whole file when length is accessed"
                            );
                        }
                        this._length = datalength;
                        this._chunkSize = chunkSize;
                        this.lengthKnown = true;
                    };
                    if (typeof XMLHttpRequest !== "undefined") {
                        if (!ENVIRONMENT_IS_WORKER)
                            throw "Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";
                        var lazyArray = new LazyUint8Array();
                        Object.defineProperties(lazyArray, {
                            length: {
                                get: function () {
                                    if (!this.lengthKnown) {
                                        this.cacheLength();
                                    }
                                    return this._length;
                                },
                            },
                            chunkSize: {
                                get: function () {
                                    if (!this.lengthKnown) {
                                        this.cacheLength();
                                    }
                                    return this._chunkSize;
                                },
                            },
                        });
                        var properties = {
                            isDevice: false,
                            contents: lazyArray,
                        };
                    } else {
                        var properties = {
                            isDevice: false,
                            url: url,
                        };
                    }
                    var node = FS.createFile(parent, name, properties, canRead, canWrite);
                    if (properties.contents) {
                        node.contents = properties.contents;
                    } else if (properties.url) {
                        node.contents = null;
                        node.url = properties.url;
                    }
                    Object.defineProperties(node, {
                        usedBytes: {
                            get: function () {
                                return this.contents.length;
                            },
                        },
                    });
                    var stream_ops = {};
                    var keys = Object.keys(node.stream_ops);
                    keys.forEach(function (key) {
                        var fn = node.stream_ops[key];
                        stream_ops[key] = function forceLoadLazyFile() {
                            if (!FS.forceLoadFile(node)) {
                                throw new FS.ErrnoError(29);
                            }
                            return fn.apply(null, arguments);
                        };
                    });
                    stream_ops.read = function stream_ops_read(
                        stream,
                        buffer,
                        offset,
                        length,
                        position
                    ) {
                        if (!FS.forceLoadFile(node)) {
                            throw new FS.ErrnoError(29);
                        }
                        var contents = stream.node.contents;
                        if (position >= contents.length) return 0;
                        var size = Math.min(contents.length - position, length);
                        if (contents.slice) {
                            for (var i = 0; i < size; i++) {
                                buffer[offset + i] = contents[position + i];
                            }
                        } else {
                            for (var i = 0; i < size; i++) {
                                buffer[offset + i] = contents.get(position + i);
                            }
                        }
                        return size;
                    };
                    node.stream_ops = stream_ops;
                    return node;
                },
                createPreloadedFile: function (
                    parent,
                    name,
                    url,
                    canRead,
                    canWrite,
                    onload,
                    onerror,
                    dontCreateFile,
                    canOwn,
                    preFinish
                ) {
                    Browser.init();
                    var fullname = name
                        ? PATH_FS.resolve(PATH.join2(parent, name))
                        : parent;

                    function processData(byteArray) {
                        function finish(byteArray) {
                            if (preFinish) preFinish();
                            if (!dontCreateFile) {
                                FS.createDataFile(
                                    parent,
                                    name,
                                    byteArray,
                                    canRead,
                                    canWrite,
                                    canOwn
                                );
                            }
                            if (onload) onload();
                            removeRunDependency();
                        }
                        var handled = false;
                        Module["preloadPlugins"].forEach(function (plugin) {
                            if (handled) return;
                            if (plugin["canHandle"](fullname)) {
                                plugin["handle"](byteArray, fullname, finish, function () {
                                    if (onerror) onerror();
                                    removeRunDependency();
                                });
                                handled = true;
                            }
                        });
                        if (!handled) finish(byteArray);
                    }
                    addRunDependency();
                    if (typeof url == "string") {
                        Browser.asyncLoad(
                            url,
                            function (byteArray) {
                                processData(byteArray);
                            },
                            onerror
                        );
                    } else {
                        processData(url);
                    }
                },
                indexedDB: function () {
                    return (
                        window.indexedDB ||
                        window.mozIndexedDB ||
                        window.webkitIndexedDB ||
                        window.msIndexedDB
                    );
                },
                DB_NAME: function () {
                    return "EM_FS_" + window.location.pathname;
                },
                DB_VERSION: 20,
                DB_STORE_NAME: "FILE_DATA",
                saveFilesToDB: function (paths, onload, onerror) {
                    onload = onload || function () { };
                    onerror = onerror || function () { };
                    var indexedDB = FS.indexedDB();
                    try {
                        var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
                    } catch (e) {
                        return onerror(e);
                    }
                    openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
                        out("creating db");
                        var db = openRequest.result;
                        db.createObjectStore(FS.DB_STORE_NAME);
                    };
                    openRequest.onsuccess = function openRequest_onsuccess() {
                        var db = openRequest.result;
                        var transaction = db.transaction([FS.DB_STORE_NAME], "readwrite");
                        var files = transaction.objectStore(FS.DB_STORE_NAME);
                        var ok = 0,
                            fail = 0,
                            total = paths.length;

                        function finish() {
                            if (fail == 0) onload();
                            else onerror();
                        }
                        paths.forEach(function (path) {
                            var putRequest = files.put(
                                FS.analyzePath(path).object.contents,
                                path
                            );
                            putRequest.onsuccess = function putRequest_onsuccess() {
                                ok++;
                                if (ok + fail == total) finish();
                            };
                            putRequest.onerror = function putRequest_onerror() {
                                fail++;
                                if (ok + fail == total) finish();
                            };
                        });
                        transaction.onerror = onerror;
                    };
                    openRequest.onerror = onerror;
                },
                loadFilesFromDB: function (paths, onload, onerror) {
                    onload = onload || function () { };
                    onerror = onerror || function () { };
                    var indexedDB = FS.indexedDB();
                    try {
                        var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
                    } catch (e) {
                        return onerror(e);
                    }
                    openRequest.onupgradeneeded = onerror;
                    openRequest.onsuccess = function openRequest_onsuccess() {
                        var db = openRequest.result;
                        try {
                            var transaction = db.transaction([FS.DB_STORE_NAME], "readonly");
                        } catch (e) {
                            onerror(e);
                            return;
                        }
                        var files = transaction.objectStore(FS.DB_STORE_NAME);
                        var ok = 0,
                            fail = 0,
                            total = paths.length;

                        function finish() {
                            if (fail == 0) onload();
                            else onerror();
                        }
                        paths.forEach(function (path) {
                            var getRequest = files.get(path);
                            getRequest.onsuccess = function getRequest_onsuccess() {
                                if (FS.analyzePath(path).exists) {
                                    FS.unlink(path);
                                }
                                FS.createDataFile(
                                    PATH.dirname(path),
                                    PATH.basename(path),
                                    getRequest.result,
                                    true,
                                    true,
                                    true
                                );
                                ok++;
                                if (ok + fail == total) finish();
                            };
                            getRequest.onerror = function getRequest_onerror() {
                                fail++;
                                if (ok + fail == total) finish();
                            };
                        });
                        transaction.onerror = onerror;
                    };
                    openRequest.onerror = onerror;
                },
            };
            var SYSCALLS = {
                mappings: {},
                DEFAULT_POLLMASK: 5,
                umask: 511,
                calculateAt: function (dirfd, path) {
                    if (path[0] !== "/") {
                        var dir;
                        if (dirfd === -100) {
                            dir = FS.cwd();
                        } else {
                            var dirstream = FS.getStream(dirfd);
                            if (!dirstream) throw new FS.ErrnoError(8);
                            dir = dirstream.path;
                        }
                        path = PATH.join2(dir, path);
                    }
                    return path;
                },
                doStat: function (func, path, buf) {
                    try {
                        var stat = func(path);
                    } catch (e) {
                        if (
                            e &&
                            e.node &&
                            PATH.normalize(path) !== PATH.normalize(FS.getPath(e.node))
                        ) {
                            return -54;
                        }
                        throw e;
                    }
                    HEAP32[buf >> 2] = stat.dev;
                    HEAP32[(buf + 4) >> 2] = 0;
                    HEAP32[(buf + 8) >> 2] = stat.ino;
                    HEAP32[(buf + 12) >> 2] = stat.mode;
                    HEAP32[(buf + 16) >> 2] = stat.nlink;
                    HEAP32[(buf + 20) >> 2] = stat.uid;
                    HEAP32[(buf + 24) >> 2] = stat.gid;
                    HEAP32[(buf + 28) >> 2] = stat.rdev;
                    HEAP32[(buf + 32) >> 2] = 0;
                    (tempI64 = [
                        stat.size >>> 0,
                        ((tempDouble = stat.size),
                            +Math_abs(tempDouble) >= 1
                                ? tempDouble > 0
                                    ? (Math_min(+Math_floor(tempDouble / 4294967296), 4294967295) |
                                        0) >>>
                                    0
                                    : ~~+Math_ceil(
                                        (tempDouble - +(~~tempDouble >>> 0)) / 4294967296
                                    ) >>> 0
                                : 0),
                    ]),
                        (HEAP32[(buf + 40) >> 2] = tempI64[0]),
                        (HEAP32[(buf + 44) >> 2] = tempI64[1]);
                    HEAP32[(buf + 48) >> 2] = 4096;
                    HEAP32[(buf + 52) >> 2] = stat.blocks;
                    HEAP32[(buf + 56) >> 2] = (stat.atime.getTime() / 1e3) | 0;
                    HEAP32[(buf + 60) >> 2] = 0;
                    HEAP32[(buf + 64) >> 2] = (stat.mtime.getTime() / 1e3) | 0;
                    HEAP32[(buf + 68) >> 2] = 0;
                    HEAP32[(buf + 72) >> 2] = (stat.ctime.getTime() / 1e3) | 0;
                    HEAP32[(buf + 76) >> 2] = 0;
                    (tempI64 = [
                        stat.ino >>> 0,
                        ((tempDouble = stat.ino),
                            +Math_abs(tempDouble) >= 1
                                ? tempDouble > 0
                                    ? (Math_min(+Math_floor(tempDouble / 4294967296), 4294967295) |
                                        0) >>>
                                    0
                                    : ~~+Math_ceil(
                                        (tempDouble - +(~~tempDouble >>> 0)) / 4294967296
                                    ) >>> 0
                                : 0),
                    ]),
                        (HEAP32[(buf + 80) >> 2] = tempI64[0]),
                        (HEAP32[(buf + 84) >> 2] = tempI64[1]);
                    return 0;
                },
                doMsync: function (addr, stream, len, flags, offset) {
                    var buffer = HEAPU8.slice(addr, addr + len);
                    FS.msync(stream, buffer, offset, len, flags);
                },
                doMkdir: function (path, mode) {
                    path = PATH.normalize(path);
                    if (path[path.length - 1] === "/")
                        path = path.substr(0, path.length - 1);
                    FS.mkdir(path, mode, 0);
                    return 0;
                },
                doMknod: function (path, mode, dev) {
                    switch (mode & 61440) {
                        case 32768:
                        case 8192:
                        case 24576:
                        case 4096:
                        case 49152:
                            break;
                        default:
                            return -28;
                    }
                    FS.mknod(path, mode, dev);
                    return 0;
                },
                doReadlink: function (path, buf, bufsize) {
                    if (bufsize <= 0) return -28;
                    var ret = FS.readlink(path);
                    var len = Math.min(bufsize, lengthBytesUTF8(ret));
                    var endChar = HEAP8[buf + len];
                    stringToUTF8(ret, buf, bufsize + 1);
                    HEAP8[buf + len] = endChar;
                    return len;
                },
                doAccess: function (path, amode) {
                    if (amode & ~7) {
                        return -28;
                    }
                    var node;
                    var lookup = FS.lookupPath(path, {
                        follow: true,
                    });
                    node = lookup.node;
                    if (!node) {
                        return -44;
                    }
                    var perms = "";
                    if (amode & 4) perms += "r";
                    if (amode & 2) perms += "w";
                    if (amode & 1) perms += "x";
                    if (perms && FS.nodePermissions(node, perms)) {
                        return -2;
                    }
                    return 0;
                },
                doDup: function (path, flags, suggestFD) {
                    var suggest = FS.getStream(suggestFD);
                    if (suggest) FS.close(suggest);
                    return FS.open(path, flags, 0, suggestFD, suggestFD).fd;
                },
                doReadv: function (stream, iov, iovcnt, offset) {
                    var ret = 0;
                    for (var i = 0; i < iovcnt; i++) {
                        var ptr = HEAP32[(iov + i * 8) >> 2];
                        var len = HEAP32[(iov + (i * 8 + 4)) >> 2];
                        var curr = FS.read(stream, HEAP8, ptr, len, offset);
                        if (curr < 0) return -1;
                        ret += curr;
                        if (curr < len) break;
                    }
                    return ret;
                },
                doWritev: function (stream, iov, iovcnt, offset) {
                    var ret = 0;
                    for (var i = 0; i < iovcnt; i++) {
                        var ptr = HEAP32[(iov + i * 8) >> 2];
                        var len = HEAP32[(iov + (i * 8 + 4)) >> 2];
                        var curr = FS.write(stream, HEAP8, ptr, len, offset);
                        if (curr < 0) return -1;
                        ret += curr;
                    }
                    return ret;
                },
                varargs: undefined,
                get: function () {
                    SYSCALLS.varargs += 4;
                    var ret = HEAP32[(SYSCALLS.varargs - 4) >> 2];
                    return ret;
                },
                getStr: function (ptr) {
                    var ret = UTF8ToString(ptr);
                    return ret;
                },
                getStreamFromFD: function (fd) {
                    var stream = FS.getStream(fd);
                    if (!stream) throw new FS.ErrnoError(8);
                    return stream;
                },
                get64: function (low, high) {
                    return low;
                },
            };

            function ___sys_fcntl64(fd, cmd, varargs) {
                SYSCALLS.varargs = varargs;
                try {
                    var stream = SYSCALLS.getStreamFromFD(fd);
                    switch (cmd) {
                        case 0: {
                            var arg = SYSCALLS.get();
                            if (arg < 0) {
                                return -28;
                            }
                            var newStream;
                            newStream = FS.open(stream.path, stream.flags, 0, arg);
                            return newStream.fd;
                        }
                        case 1:
                        case 2:
                            return 0;
                        case 3:
                            return stream.flags;
                        case 4: {
                            var arg = SYSCALLS.get();
                            stream.flags |= arg;
                            return 0;
                        }
                        case 12: {
                            var arg = SYSCALLS.get();
                            var offset = 0;
                            HEAP16[(arg + offset) >> 1] = 2;
                            return 0;
                        }
                        case 13:
                        case 14:
                            return 0;
                        case 16:
                        case 8:
                            return -28;
                        case 9:
                            setErrNo(28);
                            return -1;
                        default: {
                            return -28;
                        }
                    }
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return -e.errno;
                }
            }

            function ___sys_ioctl(fd, op, varargs) {
                SYSCALLS.varargs = varargs;
                try {
                    var stream = SYSCALLS.getStreamFromFD(fd);
                    switch (op) {
                        case 21509:
                        case 21505: {
                            if (!stream.tty) return -59;
                            return 0;
                        }
                        case 21510:
                        case 21511:
                        case 21512:
                        case 21506:
                        case 21507:
                        case 21508: {
                            if (!stream.tty) return -59;
                            return 0;
                        }
                        case 21519: {
                            if (!stream.tty) return -59;
                            var argp = SYSCALLS.get();
                            HEAP32[argp >> 2] = 0;
                            return 0;
                        }
                        case 21520: {
                            if (!stream.tty) return -59;
                            return -28;
                        }
                        case 21531: {
                            var argp = SYSCALLS.get();
                            return FS.ioctl(stream, op, argp);
                        }
                        case 21523: {
                            if (!stream.tty) return -59;
                            return 0;
                        }
                        case 21524: {
                            if (!stream.tty) return -59;
                            return 0;
                        }
                        default:
                            abort("bad ioctl syscall " + op);
                    }
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return -e.errno;
                }
            }

            function ___sys_open(path, flags, varargs) {
                SYSCALLS.varargs = varargs;
                try {
                    var pathname = SYSCALLS.getStr(path);
                    var mode = SYSCALLS.get();
                    var stream = FS.open(pathname, flags, mode);
                    return stream.fd;
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return -e.errno;
                }
            }

            function ___sys_rmdir(path) {
                try {
                    path = SYSCALLS.getStr(path);
                    FS.rmdir(path);
                    return 0;
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return -e.errno;
                }
            }

            function ___sys_umask(mask) {
                try {
                    var old = SYSCALLS.umask;
                    SYSCALLS.umask = mask;
                    return old;
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return -e.errno;
                }
            }

            function ___sys_unlink(path) {
                try {
                    path = SYSCALLS.getStr(path);
                    FS.unlink(path);
                    return 0;
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return -e.errno;
                }
            }

            function ___sys_wait4(pid, wstart, options, rusage) {
                try {
                    abort("cannot wait on child processes");
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return -e.errno;
                }
            }

            function _emscripten_memcpy_big(dest, src, num) {
                HEAPU8.copyWithin(dest, src, src + num);
            }

            function _emscripten_get_heap_size() {
                return HEAPU8.length;
            }

            function emscripten_realloc_buffer(size) {
                try {
                    wasmMemory.grow((size - buffer.byteLength + 65535) >>> 16);
                    updateGlobalBufferAndViews(wasmMemory.buffer);
                    return 1;
                } catch (e) { }
            }

            function _emscripten_resize_heap(requestedSize) {
                requestedSize = requestedSize >>> 0;
                var oldSize = _emscripten_get_heap_size();
                var PAGE_MULTIPLE = 65536;
                var maxHeapSize = 2147483648;
                if (requestedSize > maxHeapSize) {
                    return false;
                }
                var minHeapSize = 16777216;
                for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
                    var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown);
                    overGrownHeapSize = Math.min(
                        overGrownHeapSize,
                        requestedSize + 100663296
                    );
                    var newSize = Math.min(
                        maxHeapSize,
                        alignUp(
                            Math.max(minHeapSize, requestedSize, overGrownHeapSize),
                            PAGE_MULTIPLE
                        )
                    );
                    var replacement = emscripten_realloc_buffer(newSize);
                    if (replacement) {
                        return true;
                    }
                }
                return false;
            }
            var ENV = {};

            function __getExecutableName() {
                return thisProgram || "./this.program";
            }

            function getEnvStrings() {
                if (!getEnvStrings.strings) {
                    var env = {
                        USER: "web_user",
                        LOGNAME: "web_user",
                        PATH: "/",
                        PWD: "/",
                        HOME: "/home/web_user",
                        LANG:
                            (
                                (typeof navigator === "object" &&
                                    navigator.languages &&
                                    navigator.languages[0]) ||
                                "C"
                            ).replace("-", "_") + ".UTF-8",
                        _: __getExecutableName(),
                    };
                    for (var x in ENV) {
                        env[x] = ENV[x];
                    }
                    var strings = [];
                    for (var x in env) {
                        strings.push(x + "=" + env[x]);
                    }
                    getEnvStrings.strings = strings;
                }
                return getEnvStrings.strings;
            }

            function _environ_get(__environ, environ_buf) {
                var bufSize = 0;
                getEnvStrings().forEach(function (string, i) {
                    var ptr = environ_buf + bufSize;
                    HEAP32[(__environ + i * 4) >> 2] = ptr;
                    writeAsciiToMemory(string, ptr);
                    bufSize += string.length + 1;
                });
                return 0;
            }

            function _environ_sizes_get(penviron_count, penviron_buf_size) {
                var strings = getEnvStrings();
                HEAP32[penviron_count >> 2] = strings.length;
                var bufSize = 0;
                strings.forEach(function (string) {
                    bufSize += string.length + 1;
                });
                HEAP32[penviron_buf_size >> 2] = bufSize;
                return 0;
            }

            function _exit(status) {
                exit(status);
            }

            function _fd_close(fd) {
                try {
                    var stream = SYSCALLS.getStreamFromFD(fd);
                    FS.close(stream);
                    return 0;
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return e.errno;
                }
            }

            function _fd_fdstat_get(fd, pbuf) {
                try {
                    var stream = SYSCALLS.getStreamFromFD(fd);
                    var type = stream.tty
                        ? 2
                        : FS.isDir(stream.mode)
                            ? 3
                            : FS.isLink(stream.mode)
                                ? 7
                                : 4;
                    HEAP8[pbuf >> 0] = type;
                    return 0;
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return e.errno;
                }
            }

            function _fd_read(fd, iov, iovcnt, pnum) {
                try {
                    var stream = SYSCALLS.getStreamFromFD(fd);
                    var num = SYSCALLS.doReadv(stream, iov, iovcnt);
                    HEAP32[pnum >> 2] = num;
                    return 0;
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return e.errno;
                }
            }

            function _fd_seek(fd, offset_low, offset_high, whence, newOffset) {
                try {
                    var stream = SYSCALLS.getStreamFromFD(fd);
                    var HIGH_OFFSET = 4294967296;
                    var offset = offset_high * HIGH_OFFSET + (offset_low >>> 0);
                    var DOUBLE_LIMIT = 9007199254740992;
                    if (offset <= -DOUBLE_LIMIT || offset >= DOUBLE_LIMIT) {
                        return -61;
                    }
                    FS.llseek(stream, offset, whence);
                    (tempI64 = [
                        stream.position >>> 0,
                        ((tempDouble = stream.position),
                            +Math_abs(tempDouble) >= 1
                                ? tempDouble > 0
                                    ? (Math_min(+Math_floor(tempDouble / 4294967296), 4294967295) |
                                        0) >>>
                                    0
                                    : ~~+Math_ceil(
                                        (tempDouble - +(~~tempDouble >>> 0)) / 4294967296
                                    ) >>> 0
                                : 0),
                    ]),
                        (HEAP32[newOffset >> 2] = tempI64[0]),
                        (HEAP32[(newOffset + 4) >> 2] = tempI64[1]);
                    if (stream.getdents && offset === 0 && whence === 0)
                        stream.getdents = null;
                    return 0;
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return e.errno;
                }
            }

            function _fd_write(fd, iov, iovcnt, pnum) {
                try {
                    var stream = SYSCALLS.getStreamFromFD(fd);
                    var num = SYSCALLS.doWritev(stream, iov, iovcnt);
                    HEAP32[pnum >> 2] = num;
                    return 0;
                } catch (e) {
                    if (typeof FS === "undefined" || !(e instanceof FS.ErrnoError))
                        abort(e);
                    return e.errno;
                }
            }

            function _popen() {
                err("missing function: popen");
                abort(-1);
            }

            function _pthread_create() {
                return 6;
            }

            function _pthread_join() { }
            var FSNode = function (parent, name, mode, rdev) {
                if (!parent) {
                    parent = this;
                }
                this.parent = parent;
                this.mount = parent.mount;
                this.mounted = null;
                this.id = FS.nextInode++;
                this.name = name;
                this.mode = mode;
                this.node_ops = {};
                this.stream_ops = {};
                this.rdev = rdev;
            };
            var readMode = 292 | 73;
            var writeMode = 146;
            Object.defineProperties(FSNode.prototype, {
                read: {
                    get: function () {
                        return (this.mode & readMode) === readMode;
                    },
                    set: function (val) {
                        val ? (this.mode |= readMode) : (this.mode &= ~readMode);
                    },
                },
                write: {
                    get: function () {
                        return (this.mode & writeMode) === writeMode;
                    },
                    set: function (val) {
                        val ? (this.mode |= writeMode) : (this.mode &= ~writeMode);
                    },
                },
                isFolder: {
                    get: function () {
                        return FS.isDir(this.mode);
                    },
                },
                isDevice: {
                    get: function () {
                        return FS.isChrdev(this.mode);
                    },
                },
            });
            FS.FSNode = FSNode;
            FS.staticInit();

            function intArrayFromString(stringy, dontAddNull, length) {
                var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1;
                var u8array = new Array(len);
                var numBytesWritten = stringToUTF8Array(
                    stringy,
                    u8array,
                    0,
                    u8array.length
                );
                if (dontAddNull) u8array.length = numBytesWritten;
                return u8array;
            }
            var asmLibraryArg = {
                a: ___assert_fail,
                s: ___clock_gettime,
                d: ___sys_fcntl64,
                i: ___sys_ioctl,
                e: ___sys_open,
                t: ___sys_rmdir,
                j: ___sys_umask,
                u: ___sys_unlink,
                v: ___sys_wait4,
                n: _emscripten_memcpy_big,
                b: _emscripten_resize_heap,
                p: _environ_get,
                q: _environ_sizes_get,
                c: _exit,
                f: _fd_close,
                r: _fd_fdstat_get,
                h: _fd_read,
                m: _fd_seek,
                g: _fd_write,
                memory: wasmMemory,
                o: _popen,
                l: _pthread_create,
                k: _pthread_join,
                table: wasmTable,
            };
            createWasm();
            var ___wasm_call_ctors = (Module["___wasm_call_ctors"] = function () {
                return (___wasm_call_ctors = Module["___wasm_call_ctors"] =
                    Module["asm"]["w"]).apply(null, arguments);
            });
            var _malloc = (Module["_malloc"] = function () {
                return (_malloc = Module["_malloc"] = Module["asm"]["x"]).apply(
                    null,
                    arguments
                );
            });
            var ___errno_location = (Module["___errno_location"] = function () {
                return (___errno_location = Module["___errno_location"] =
                    Module["asm"]["y"]).apply(null, arguments);
            });
            Module["_main"] = function () {
                return (Module["_main"] = Module["asm"]["z"]).apply(null, arguments);
            };
            var stackAlloc = (Module["stackAlloc"] = function () {
                return (stackAlloc = Module["stackAlloc"] = Module["asm"]["A"]).apply(
                    null,
                    arguments
                );
            });
            Module["dynCall_vi"] = function () {
                return (Module["dynCall_vi"] = Module["asm"]["B"]).apply(
                    null,
                    arguments
                );
            };
            var calledRun;

            function ExitStatus(status) {
                this.name = "ExitStatus";
                this.message = "Program terminated with exit(" + status + ")";
                this.status = status;
            }
            dependenciesFulfilled = function runCaller() {
                if (!calledRun) run();
                if (!calledRun) dependenciesFulfilled = runCaller;
            };

            function callMain(args) {
                var entryFunction = Module["_main"];
                args = args || [];
                // console.log(args);
                function comArgs(command) {
                    var argc = command.length + 1;
                    var argv = stackAlloc((argc + 1) * 4);
                    HEAP32[argv >> 2] = allocateUTF8OnStack(thisProgram);
                    for (var i = 1; i < argc; i++) {
                        HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(command[i - 1]);
                    }
                    HEAP32[(argv >> 2) + argc] = 0;
                    return { argc, argv };
                }

                try {
                    var ret;
                    for (let index = 0; index < args.length; index++) {
                        const a = args[index];
                        // console.log(a);
                        // let outIndex = a.findIndex(f=>f==='-o')
                        // a[outIndex+1] = '/out/'
                        let command = a.split(" ").filter((f) => Boolean(f));

                        let { argc, argv } = comArgs(command);
                        // console.log(command);
                        // console.log('argc, argv:',argc, argv);
                        ret = entryFunction(argc, argv);
                        // console.log(ret);
                        if (ret !== 0) break;
                        // console.log(index+'_______');
                    }
                    exit(ret, true);
                } catch (e) {
                    if (e instanceof ExitStatus) {
                        return;
                    } else if (e == "unwind") {
                        noExitRuntime = true;
                        return;
                    } else {
                        var toLog = e;
                        if (e && typeof e === "object" && e.stack) {
                            toLog = [e, e.stack];
                        }
                        err("exception thrown: " + toLog);
                        quit_(1, e);
                    }
                } finally {
                }
            }

            function run(args) {
                args = args || arguments_;

                if (runDependencies > 0) {
                    return;
                }
                preRun();
                if (runDependencies > 0) return;

                function doRun() {
                    if (calledRun) return;
                    calledRun = true;
                    Module["calledRun"] = true;
                    if (ABORT) return;
                    initRuntime();
                    preMain();
                    readyPromiseResolve(Module);
                    if (Module["onRuntimeInitialized"]) Module["onRuntimeInitialized"]();
                    if (shouldRunNow) {
                        callMain(args);

                        // for (let index = 0; index < args.length; index++) {
                        // const element = args[index];

                        // }
                    }
                    postRun();
                }
                if (Module["setStatus"]) {
                    Module["setStatus"]("Running...");
                    setTimeout(function () {
                        setTimeout(function () {
                            Module["setStatus"]("");
                        }, 1);
                        doRun();
                    }, 1);
                } else {
                    doRun();
                }
            }
            Module["run"] = run;

            function exit(status, implicit) {
                if (implicit && noExitRuntime && status === 0) {
                    return;
                }
                if (noExitRuntime);
                else {
                    ABORT = true;
                    if (Module["onExit"]) Module["onExit"](status);
                }
                quit_(status, new ExitStatus(status));
            }
            if (Module["preInit"]) {
                if (typeof Module["preInit"] == "function")
                    Module["preInit"] = [Module["preInit"]];
                while (Module["preInit"].length > 0) {
                    Module["preInit"].pop()();
                }
            }
            var shouldRunNow = true;
            if (Module["noInitialRun"]) shouldRunNow = false;
            noExitRuntime = true;
            run();

            return gifsicle.ready;
        };
    })();
    // if (typeof exports === 'object' && typeof module === 'object')
    //   module.exports = gifsicle;
    // else if (typeof define === 'function' && define['amd'])
    //   define([], function () {
    //     return gifsicle;
    //   });
    // else if (typeof exports === 'object')
    //   exports["gifsicle"] = gifsicle;
    // else {
    //   export default gifsicle
    // }

    // Object.defineProperty(exports, "__esModule", {
    //   value: true
    // });
    // // exports.flush = exports.stderr = exports.stdout = void 0;

    /* eslint-disable no-console */
    let out = "";
    /**
     * Process stdout stream
     *
     * @param {number} char Next char in stream
     */

    const stdout = (char) => {
        out += String.fromCharCode(char);

        if (char === 10) {
            console.log(out);
            out = "";
        }
    };

    // exports.stdout = stdout;
    let err = "";
    /**
     * Process stderr stream
     *
     * @param {number} char Next char in stream
     */

    const stderr = (char) => {
        err += String.fromCharCode(char);

        if (char === 10) {
            console.error(err);
            err = "";
        }
    };
    /**
     * Flush remaining buffer
     */

    // exports.stderr = stderr;

    const flush = () => {
        if (out.length > 0) {
            console.log(out);
            out = "";
        }

        if (err.length > 0) {
            console.error(err);
            err = "";
        }
    };

    var _io = {
        flush,
        stderr,
        stdout,
    };

    const queue = [];
    /**
     * Initialize the gifsicle module
     */

    const initModule = () => {
        return new Promise((resolve) => {
            // add a new job to the queue
            queue.push(resolve); // start it if there is no queue

            if (queue.length === 1) {
                queue[0]();
            }
        });
    };
    /**
     * Reset the gifsicle module
     */
    const resetModule = () => {
        if (queue.length > 0) {
            // remove finished job
            queue.shift(); // trigger next job
            if (queue.length > 0) {
                queue[0]();
            }
        }
    };
    /**
     * Encode an input image using Gifsicle
     *
     * @async
     * @param {Buffer} data Image input buffer
     * @param {EncodeOptions} command
     * @returns {Buffer} Processed image buffer
     */
    const encode = async (obj = {}) => {
        let {
            data = null,
            command = [],
            folder = [],
            isStrict = false,
        } = obj;
        await initModule();
        return new Promise((resolve, reject) => {
            let resolved = false;
            let err = ''
           
            gifsicle_c({
                stdout: _io.stdout,
                // stderr: _io.stderr,
                stderr: (char) => {
                    err += String.fromCharCode(char);
                    if (char === 10) {
                        console.error(err);
                        if (isStrict) {
                            reject(err)
                        }
                    }
                },
                arguments: command,
                // input: new Uint8Array(image.buffer),
                input: data,
                folder: folder,
                output: (res) => {
                    resolve(res);
                    resolved = true;
                },
            }).then(() => {
                (0, _io.flush)();

                if (!resolved) {
                    reject();
                }

                resetModule();
            });
        });
    };

    return encode;
})();
